когда мы должны сделать оператор присваивания приватным и не реализовывать - PullRequest
3 голосов
/ 06 марта 2011

Это старый экзаменационный вопрос, который просит нас писать операторы присваивания и копировать конструкторы, деструкторы, когда это имеет смысл.

С учетом следующего кода:

class U { /* code not specified here */ };
class A { /* code not specified here */ private: U& u_; };

Я узнал, что Ответ таков: A содержит ссылку C ++ на экземпляр U, который может быть скопирован, но не может быть сброшен. Поэтому вы должны:

• Написать конструктор копирования, который инициализирует свой U тому же экземпляру, на который ссылается исходный экземпляр A.

• Сделать свой оператор присваивания частным и не реализовывать

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

  class U{
    public:
        int u;
    };

    class A{
    public:
        A(U& u):u_(u){}
        A& operator=(const A& a){
            u_ = a.u_;
            return *this;
        }
        U& u_;
    };

    int main(){
        U u1;
        U u2;
        A a1(u1);
        A a2(u2);
        a1 = a2;
        a1.u_.u = 1;
        a2.u_.u = 2;
        cout << "a1.u_.u : " << a1.u_.u << endl;
        cout << "a2.u_.u : " <<  a2.u_.u << endl;
    }

Заранее спасибо.

Ответы [ 5 ]

2 голосов
/ 06 марта 2011

Ссылки не могут быть изменены, чтобы ссылаться на что-то еще. Однако вы можете делать то, что вы делаете здесь, потому что делаете:

u_ = a.u_;

в действительности меняет значение, на которое ссылаются. Он отмечает изменение , на которое ссылается значение .

2 голосов
/ 06 марта 2011
A& operator=(const A& a){
    u_ = a.u_;
    return *this;
}

Не будет работать должным образом, U, которым будут назначены контрольные точки.
Конечно, вы можете реализовать оператор присваивания, даже если класс содержит ссылку, если эта ссылка можетбыть назначенным (что если указанный класс имеет operator= only privat?), а ссылка не является const U& (поэтому не может быть назначена).

1 голос
/ 06 марта 2011

означает ли это, что я никогда не смогу использовать оператор присваивания всякий раз, когда класс содержит данные референтного члена?

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

1 голос
/ 06 марта 2011

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

Для компилятора следующие классы эквивалентны, обратите внимание, что версия указателя разыменовывает указатели для копирования содержимого:

class A_Ref{
public:
    A_Ref(U& u):u_(u){}
    A_Ref& operator=(const A_Ref& a){
        u_ = a.u_;
        return *this;
    }
    U& u_;
};

class A_Ptr{
public:
    A_Ptr(U* u):u_(u){}
    A_Ptr& operator=(const A_Ptr& a){
        *u_ = *a.u_;
        return *this;
    }
    U* u_;
};
0 голосов
/ 06 марта 2011

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

...