Самоинициализация 'A a = a;' позволил?
Этот код не выполняется во время выполнения в конструкторе копирования.
Но компилятор (MSVS2008) не выдает никаких предупреждений.
Не могли бы вы объяснить (желательно привести стандарт), является ли этот код незаконным или что?
Я понимаю, что A a = a; никогда не должно быть написано в первую очередь, но я ищу теоретический фон.
class A
{
public:
A()
:p(new int)
{
}
A(const A& rv)
{
p = new int(*rv.p);
}
~A()
{
delete p;
}
private:
int *p;
};
int main()
{
A a = a;
}
4 ответа
Ваш код вызывает не стандартный конструктор, а конструктор копирования, поэтому вы обращаетесь к неинициализированному указателю.
Интересное чтение по самостоятельному заданию: http://www.gotw.ca/gotw/011.htm
В частности, обратите внимание на "Постскриптум № 1" в отношении этого вопроса и некоторые из приведенных ответов.
В соответствии со стандартом (12.6.1 [class.expl.init]) самостоятельная инициализация совершенно легальна.
Поэтому следующее законно.
A a = a;
Вам просто нужно написать свой конструктор копирования, чтобы справиться с ним правильно.
A(const A& rv)
{
if(&rv == this) {
p = new int(0);
return;
}
p = new int(*rv.p);
}
Изменить: Обновлен код на основе комментариев.
A a = a;
определенно не должно быть написано. Но a = a
может быть написано. Ваш оператор присваивания должен проверить &rv == this
и ничего не делать в случае самокопирования.
О да, вам нужно написать оператор присваивания для класса А.