Подтвердить что ты не робот

Перегрузка оператора назначения в С++

Я использовал следующий код для перегрузки оператора присваивания:

SimpleCircle SimpleCircle::operator=(const SimpleCircle & rhs)
{
     if(this == &rhs)
        return *this;
     itsRadius = rhs.getRadius();
     return *this;
}

My Copy Constructor:

SimpleCircle::SimpleCircle(const SimpleCircle & rhs)
{
    itsRadius = rhs.getRadius();
}

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

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs)
{
    if(this == &rhs)
       return *this;
    itsRadius = rhs.getRadius();
    return *this;
}

Его работа отлично и проблема конструктора копий устранена, но есть ли какие-то неизвестные проблемы (для меня) относительно этого?

4b9b3361

Ответ 1

Нет проблем со второй версией оператора присваивания. На самом деле это стандартный способ для оператора присваивания.

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

Ответ 2

В сложившихся обстоятельствах вам почти наверняка будет лучше пропустить проверку самозадачи - когда вы назначаете только одного члена, который, кажется, является простым типом (возможно, двойным), он обычно быстрее делает это чем избегать его, поэтому вы получите:

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs)
{
    itsRadius = rhs.getRadius(); // or just `itsRadius = rhs.itsRadius;`
    return *this;
}

Я понимаю, что многие старые и/или более качественные книги советуют проверять самостоятельное назначение. По крайней мере, по моему опыту, это достаточно редко, что вам лучше без него (и если оператор зависит от него для правильности, он почти наверняка не является исключением).

В стороне, я бы отметил, что для определения круга вам обычно нужен центр и радиус, а когда вы копируете или назначаете, вы хотите скопировать/назначить оба.

Ответ 3

Вторая довольно стандартная. Вы часто предпочитаете возвращать ссылку из оператора присваивания, чтобы утверждения типа a = b = c; разрешались, как ожидалось. Я не могу думать о каких-либо случаях, когда я хотел бы вернуть копию из задания.

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

Edit:

Вот некоторые основные вызовы:

SimpleCircle x; // default constructor
SimpleCircle y(x); // copy constructor
x = y; // assignment operator

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

SimpleCircle SimpleCircle::operator=(const SimpleCircle & rhs)
{
     if(this == &rhs)
        return *this; // calls copy constructor SimpleCircle(*this)
     itsRadius = rhs.getRadius(); // copy member
     return *this; // calls copy constructor
}

Он вызывает конструктор копирования и передает ссылку на this, чтобы построить возвращаемую копию. Теперь во втором примере мы избегаем копирования, просто вернув ссылку на this

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs)
{
    if(this == &rhs)
       return *this; // return reference to this (no copy)
    itsRadius = rhs.getRadius(); // copy member
    return *this; // return reference to this (no copy)
}

Ответ 4

это правильный способ использования перегрузки оператора теперь вы получаете свой объект по ссылке избегая копирования значений.

Ответ 5

это может быть полезно:

// Operator overloading in C++
//assignment operator overloading
#include<iostream>
using namespace std;

class Employee
{
private:
int idNum;
double salary;
public:
Employee ( ) {
    idNum = 0, salary = 0.0;
}

void setValues (int a, int b);
void operator= (Employee &emp );

};

void Employee::setValues ( int idN , int sal )
{

salary = sal; idNum = idN;

}

void Employee::operator = (Employee &emp)  // Assignment operator overloading function
{
salary = emp.salary;
}

int main ( )
{

Employee emp1;
emp1.setValues(10,33);
Employee emp2;
emp2 = emp1; // emp2 is calling object using assignment operator

}