Объект, который инициализирует себя в C++

Например, у меня есть код:

class test{
    public:

    test(){
        cout<<endl<<"TEST";
    }

    void another(){
        cout<<endl<<"Another";
    }

};

int main(){
    test chk = chk;
    chk.another();
}

Здесь я сделал инициализацию вновь созданного объекта типа test к себе.

Служит ли такая инициализация специальным назначением, выполняет ли эта инициализация что-либо кроме инициализации test chk; вместо test chk = chk;?

Я понимаю, что конструктор нельзя вызвать, если объект инициализирован сам по себе, но почему?

Я хотел бы узнать больше о такой инициализации объекта для себя.

2 ответа

Решение

Я немного изменил ваш код и надеюсь, что вы поймете:

class test{
    public:
        test(){ cout<<endl<<"TEST"; }

        test(const test& in)
        {   
            if ( this == &in)
            {   
                cout<<endl<<"Self init";
            }
            cout<<endl<<"Copy ctor";
        }

        void another(){ cout<<endl<<"Another"; }
};  

int main(){
    test chk = chk;
    chk.another();
    cout<<endl;
}  

Если вы сейчас позвоните по своему коду, вы получите следующий вывод:

Self init
Copy ctor
Another

Одно замечание к вашему cout<<endl заявления. Вы последний выход скрыты, потому что нет endl после последнего выхода. cout буферизуется, что означает, что он будет записывать в вашу консоль только после следующего endl или буфер заполнен. Так что еще лучше написать: cout<<"something"<<endl;

Для кода и инициализации:

Если вы берете адрес входного объекта в своем конструкторе копирования, вы можете проверить, делаете ли вы копию для себя. Это хорошая практика, потому что вам нужен собственный конструктор копирования, если вы выделили память, которую нельзя скопировать с помощью конструктора по умолчанию. Как вы можете видеть из моего примера, адрес this а также in это то же самое, что означает, что конструктор копирования хочет копировать в себя, что обычно неправильно, если не обрабатывается особым образом!

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

Вам разрешено написать:

test chk = chk;

[basic.scope.declarative] / р1

Потенциальная сфера действия первого j начинается сразу после этого j

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

test(const test&) {
  cout << endl << "copy ctor";
}

Имейте в виду, что это не очень хорошая практика, и она может даже привести к неопределенному поведению при некоторых обстоятельствах, и Clang всегда выдает -Wuninitialized предупреждение.

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