умные указатели — C ++ Initializer List с auto_ptr

Как это получается и работает:

class MyObject {
public:
MyObject() {}
};

struct ItemGood {
int Number;
MyObject *Object;

ItemGood(int Number, MyObject *Object) {
this->Number = Number;
this->Object = Object;
}
};

const ItemGood ItemGoodList[] =
{
{ 0, new MyObject() },
{ 1, new MyObject() }
};

И это не компилируется вообще:

class MyObject {
public:
MyObject() {}
};

struct ItemBad {
int Number;
std::auto_ptr<MyObject> AutoObject;

ItemBad(int Number, MyObject *Object) {
this->Number = Number;
AutoObject = std::auto_ptr<MyObject>(Object);
}
};

const ItemBad ItemBadList[] =
{
{ 0, new MyObject() },
{ 1, new MyObject() }
};

Ошибка, которую выдает компилятор:

нет подходящей функции для вызова ItemBad :: ItemBad (ItemBad)

Я не понимаю, почему что-то пытается вызвать этот конструктор, я не понимаю, что на самом деле происходит в этом списке инициализатора.

1

Решение

Так как std::auto_ptr не имеет надлежащего конструктора копирования, что означает, что у вашего класса нет надлежащего конструктора копирования, что означает, что он не может быть создан из временного — что вы и пытаетесь сделать.

Просто барахло auto_ptr и перейти к unique_ptr,

1

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

Попробуй это:

ItemBad(int Number, MyObject *Object) : Number(Number), AutoObject(Object)
{}

Похоже на std::auto_ptr на вашей платформе нет конструктора копирования, поэтому он должен быть инициализирован перед телом конструктора.

1

Кроме того, вы должны избегать использования списков инициализации, таких как:

{ 0, new MyObject() }

Вместо этого используйте конструктор:

ItemBad(0, new MyObject())

Например, компилятор MSVC генерирует ошибку для вашего «хорошего» варианта, а также для «плохого»: как только у вашего класса есть ctor, вы должны использовать его, а не списки инициализации.

0

каждый { 0, new MyObject() } выражение заменяется вызовом конструктора ItemGood(int Number, MyObject *Object)поэтому компиляторы делают что-то вроде этого:

const ItemGood ItemGoodList[] =
{
ItemGood(0, new MyObject()), // temporal 'ItemGood' 1 (const &)
ItemGood(1, new MyObject())  // temporal 'ItemGood' 2 (const &)
};

Затем сгенерированный компилятором экземпляр конструктора для ItemGood вызывается для заполнения слота массива для каждого ItemGoodнет проблем здесь

ItemBad объявление класса содержит переменную-член std::auto_ptr<MyObject> AutoObject и, как указано в других ответах, std::auto_ptr не имеет конструктора копирования, поэтому компилятор не может создать его сгенерированный компилятором скопировать конструктор для ItemBad, Когда применяется предыдущая логика, мы получаем ту же замену выражения, что и ItemGood

const ItemBad ItemGoodList[] =
{
ItemBad(0, new MyObject()), // temporal 'ItemBad' 1 (const &)
ItemBad(1, new MyObject())  // temporal 'ItemBad' 2 (const &)
};

Но здесь у нас нет копирования-конструктора, поэтому вы сообщили об ошибке, используя список инициализации в ItemBad конструктор не решит проблему и удалив MyObject назначение также не решит проблему

ItemBad(int Number, MyObject *Object) {
this->Number = Number;
// AutoObject = std::unique_ptr<MyObject>(Object);  This comment doesn't solve the problem
}

Изменить на unique_ptr как указано ранее, или используйте повышение shared_ptr

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