class — Объект, который инициализирует себя в Переполнении стека

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

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;?

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

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

3

Решение

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

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 выдает предупреждение.

1

Другие решения

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

test chk = chk;

[Basic.scope.declarative] / р1

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

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

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

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

5

По вопросам рекламы [email protected]