Оператор = перегрузка с переменной константы в C++

Я думаю, вы не понимаете, как работают параметры по умолчанию. Параметры по умолчанию - всего лишь вспомогательный синтаксис. Они облегчают вызов функции непосредственно в коде, но не изменяют саму функцию. Невозможно поддерживать любое количество параметров, если они действительно необходимы; вам нужно что-то передать.

Так что просто расширьте это, чтобы сделать синтаксическое удобство явным с перегрузкой:

func myFunction(_ str1: String?, _str2: String?)
{
    //whatever
}

func myFunction() {
    myFunction(nil, nil)
}

И тогда вы можете вызвать его.

func delay(_ function: @escaping () -> Void)
{
    if !myExternalCondition
    {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
            self.delay(function)
        }
    }
    else
    {
        function()
    }
}

Возможно, вы просто неправильно поняли, как работают замыкания. С вышеупомянутым delay, следующее хорошо, используя ваше оригинальное определение myFunction (с параметрами по умолчанию):

delay { myFunction() }

Следующее также хорошо:

delay { myFunction("xyz") }

Дело в том, что замыкание не имеет параметров. Вы можете думать о myFunction как о «закрытии», но это не правильно. Закрытие является частью {...}. Если бы у него были параметры, вы ожидали бы синтаксис x in или [119] где-то в нем.

5
задан Jon Seigel 10 April 2010 в 18:44
поделиться

6 ответов

Вы почти у цели. Несколько примечательных моментов:

  • Имя не должно быть уточнено const . A const не может быть изменен, что мы и хотим в операторе присваивания.

  • Ключевое слово C ++ - это class , а не Class , как в вашем коде (это даст вам ошибки компиляции)

  • Как отмечает Майкл Берр: «Следует отметить хотя, если класс просто содержит другие классы, которые уже должным образом поддерживают присваивание (как в этом случае с простым строковым членом), неявный, сгенерированный компилятором оператор = () будет работать нормально ». Здесь, в вашем случае, единственный член строка имеет правильный op = . Так что явное определение излишне.

  • Решение Ми почти готово. Единственное, о чем не говорится, так это о самостоятельности. Прочтите FAQ 12 .

  • Назначение - одна из трех функций-членов FAQ 27.10 . Поищи это. В нем говорится, что требование реализовать один из copy ctor, op = или dtor обычно подразумевает, что вам нужно будет реализовать и два других.

Пример исправленного кода должен быть примерно таким:

class Doctor {
  string name;
  public:
    Doctor& operator=(Doctor const& o) { 
         if (&o != this) name = o.name;
         return *this;
    }
  // ...
};
7
ответ дан 18 December 2019 в 14:51
поделиться

Стандартный способ правильно определить конструктор присваивания, чтобы обеспечить исключительную безопасность, - определить его в терминах копии Конструктор.

class Doctor
{
    public:
        Doctor& operator=(Doctor const& rhs)
        {
            if (this != &rhs)
            {
                Doctor  tmp(rhs);  // Use copy constructor here
                this->swap(tmp);   // Now Swap
            }
            return *this;
        }
        void swap(Doctor& rhs) throws()
        {
            std::swap(.....); // swap each member variable.
        }
};

Делая это таким образом, он делает исключение безопасным.
Обратите внимание, что вам просто нужно сделать своп методом без бросков, это относительно просто, если вы используете объекты STL, поскольку все они определяют своп без бросков только для этой ситуации, как Boost и все хорошие библиотеки (так что вы должны следовать комплекту ).

Если это не так, они будут ошибаться при использовании конструктора копирования. На данный момент вы не изменили свой собственный объект, поскольку вы копируете конструкцию во временный. Таким образом, вы обеспечиваете хорошую безопасность исключений, поскольку ваш объект все еще остается неизменным.

3
ответ дан 18 December 2019 в 14:51
поделиться

Декларация: Доктор и оператор = (постоянный Доктор и другие); (т. Е. Удалить Доктора ::)

оттуда вам нужно будет использовать const_cast <>, чтобы удалить постоянство переменной-члена, чтобы она работала. Обратите внимание, что на выбранном вами пути лежит только горе.

Я бы порекомендовал удалить const из объявления члена и вместо этого сделать функции-члены const по мере необходимости, чтобы показать, что они не будут влиять на объект. (Например, если у вас есть функция-член accessor, вы можете объявить это const: string getName () const {return m_name;} )

2
ответ дан 18 December 2019 в 14:51
поделиться

Как уже говорили многие ранее, элемент const указывает, что он должен быть инициализирован во время своего создания, и он не должен меняться. Если вам вообще нужно написать оператор присваивания для таких случаев и вы не можете пропустить присваивание этой переменной-члена, то сделайте его «изменяемым».

Помните; согласно стандарту C ++, «отбрасывание константы первоначально объявленной константной переменной является неопределенным поведением».

HTH, Абхай

1
ответ дан 18 December 2019 в 14:51
поделиться

Поскольку ваше имя const, единственный способ «изменить» его - через конструктор. Если вы хотите использовать оператор =, вам нужно «отстранить» строку.

.. если вы не хотите «отстранить» строку, вы можете получить несколько одинаковое поведение, создав конструктор копирования:

Doctor(const &Doctor d);

.. и реализовать его:

Doctor::Doctor(const &Doctor d)
   : name(d.name)
{
//Im pretty sure you have access to private attributes here
// My C+ is a bit rusty :) If not, make a const string getName() method
}
0
ответ дан 18 December 2019 в 14:51
поделиться

Сборка мусора прошла долгий путь с первых дней, и была проделана большая работа по предотвращению непредсказуемого долгое ожидание. Я думаю, что для современных реализаций это уже в прошлом.

Однако детали сборки мусора различаются в зависимости от реализации. Существует не так много высококачественных реализаций Lisp, поэтому вам не составит труда обратиться к их документации по сбору мусора.

(что, вероятно, и было задумано)

A = B = C;
0
ответ дан 18 December 2019 в 14:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: