Самоинициализация '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 и ничего не делать в случае самокопирования.

О да, вам нужно написать оператор присваивания для класса А.

Другие вопросы по тегам