std :: vector объекта, содержащего auto_ptr, ведет себя странно

Я хочу создать панель управления для моего приложения с использованием библиотеки Qt и для этого я создаю класс
Controls учебный класс

Controls : создайте слайдер, вращайте и добавляйте метку и выравнивайте их по горизонтали.

но когда я хочу создать std::vector<Controls> программа запускается без ошибок, но теперь управление создается вообще! так почему нет управления.

Controls.h

class Controls
{

private:

QHBoxLayout Layout ;
string Controlname;
std::auto_ptr<QLabel> Label ;
std::auto_ptr<QSlider> Slider ;
std::auto_ptr<QSpinBox> Spin ;

public:
Controls();
Controls(QLayout &Parent , string name , const int &Default_value);
Controls(const Controls &copy);
~Controls();

QLabel *const Get_Label()const { return Label.get() ; }
QSlider *const Get_Slider()const { return Slider.get() ; }
QSpinBox *const Get_Spin()const { return Spin.get() ; }
QHBoxLayout *const Get_Layout() {return &Layout;}

void SetValue(const int &newvalue);

Controls &operator= (const Controls &copy);};

Controls.cpp

Controls &Controls::operator= (const Controls &copy)
{

Label = std::auto_ptr<QLabel> ( new QLabel() ) ;
Slider = std::auto_ptr<QSlider> ( new QSlider() ) ;
Spin = std::auto_ptr<QSpinBox> ( new QSpinBox() ) ;

this->Controlname = copy.Controlname ;
this->Slider.get()->setValue( copy.Slider.get()->value() );
this->Spin.get()->setValue( copy.Spin.get()->value() );

return *this ;
}
Controls::Controls(const Controls &copy)
{
this->Controlname = copy.Controlname ;
this->Slider.get()->setValue( copy.Slider.get()->value() );
this->Spin.get()->setValue( copy.Spin.get()->value() );

}
Controls::Controls()
{

Label = std::auto_ptr<QLabel> ( new QLabel() ) ;
Slider = std::auto_ptr<QSlider> ( new QSlider() ) ;
Spin = std::auto_ptr<QSpinBox> ( new QSpinBox() ) ;

Slider->setValue(0);
Slider->setOrientation(Qt::Horizontal);
Label->setText(QString ("unamed"));
Spin->setValue(0);Layout.addWidget(Label.get() , 0 , 0);
Layout.addWidget(Slider.get() , 0 , 0);
Layout.addWidget(Spin.get() , 0 , 0);

QObject::connect(Slider.get() , SIGNAL(valueChanged(int) ) , Spin.get() , SLOT(setValue(int)));
QObject::connect(Spin.get() , SIGNAL(valueChanged(int) ) , Slider.get() , SLOT(setValue(int)));

}
Controls::Controls(QLayout &Parent , string name , const int &Default_value)
{
Controlname = name ;

Label = std::auto_ptr<QLabel> ( new QLabel() ) ;
Slider = std::auto_ptr<QSlider> ( new QSlider() ) ;
Spin = std::auto_ptr<QSpinBox> ( new QSpinBox() ) ;

Slider->setValue(Default_value*100);
Slider->setOrientation(Qt::Horizontal);
Label->setText(QString (name.c_str()));
Spin->setValue(Default_value*100);Layout.addWidget(Label.get() , 0 , 0);
Layout.addWidget(Slider.get() , 0 , 0);
Layout.addWidget(Spin.get() , 0 , 0);

QObject::connect(Slider.get() , SIGNAL(valueChanged(int) ) , Spin.get() , SLOT(setValue(int)));
QObject::connect(Spin.get() , SIGNAL(valueChanged(int) ) , Slider.get() , SLOT(setValue(int)));

Parent.addItem(&Layout);

}

void Controls::SetValue(const int &newvalue)
{
Slider.get()->setValue(newvalue);
}
Controls::~Controls()
{

}

main.cpp

int main(int argc, char *argv[])
{QApplication app (argc , argv );QVBoxLayout layout ;
auto_ptr<QWidget> Panel = auto_ptr<QWidget> (new QWidget()) ;

vector<Controls> g ;
g.push_back(Controls(layout , "WHITE_BALANCE_RED_V" , 56 ));

Panel.get()->setLayout(&layout);
Panel.get()->show();

return app.exec();

}

РЕДАКТИРОВАТЬ:

я удаляю деструктор auto_ptr из элементов управления ~, и когда я запускаю его снова, я получаю это исключение

pure virtual method called
terminate called without an active exception
  • я инициализировал ползунки и вращаюсь в конструкторе копирования

-1

Решение

Здесь есть две «странные» вещи, все связанные с auto_ptr.

Во-первых, члены-деструкторы вызываются автоматически сразу после выхода из деструктора встроенной программы. Таким образом, явное уничтожение переменных meber приводит к «двойному уничтожению», что компилятор не предназначен для управления.

(Примечание: тот факт, что переменная называется «указатель», больше не делает ее переменной): при использовании необработанных указателей и вызова delete pointer не разрушаетр, ноd, то, что auto_ptr делает само по себе).

Второе, что auto_ptr не копируется: фактически он использует операторы копирования для реализации семантики перемещения, но … контейнеры (например, std :: vector) предполагают, что копия … копировать (не перемещать).

В большинстве std::vector (и std :: list, также) реализации это не проблема, потому что разработчики обращали внимание на эту точку и избегали своих контейнеров для одновременного создания существующих копий. Но некоторые мутационные алгоритмы не могут работать последовательно, просто потому, что они непреднамеренно «перемещаются» в неправильное место — то, которое будет уничтожено сразу после возврата функции … вздох!)

Этот второй аспект решается в C ++ 11 путем реализации контейнеров, поддерживающих как копируемые, так и подвижные элементы (будучи C ++ 11, снабженным ссылками r-значения, операции копирования и перемещения являются хорошо различимыми операциями) и устарел auto_ptr в пользу unique_ptr«Не двигайся»выше скопировать «но»вместо копия».

Мораль истории: в C ++ 11 используют unique_ptr вместо auto_ptr,

В C ++ 03 не используйте auto_ptr в контейнерах или в объекте, который должен оставаться в контейнерах.

Используйте необработанный указатель и определите правильную (для вашего объекта) семантику копирования (выполнив «глубокую копию», сделав копию указателей, указывающих на копию объектов), или поделитесь семантикой (сделав указатель, чтобы указывать на одни и те же объекты, и управляйте ссылками подсчет для запуска уничтожения указанных элементов. Boost :: shared_ptr является примером такого «указателя»)

3

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

программа запускается без ошибок, но теперь управление создается вообще!

Это на самом деле очень странно, потому что в Controls::Controls(const Controls &copy) ты звонишь this->Slider.get() который вернет 0, потому что ваши участники еще не инициализированы.

Во-первых, вам нужно прочитать и понять, как использовать auto_ptr,

Во-вторых, вы должны забыть о auto_ptr и никогда не используйте его дальше. Qt имеет свои умные указатели, но они не нужны в вашем случае, потому что QObjects управляют жизнью своих детей.

Итак, в-третьих, прочитайте об управлении памятью в Qt и избавьтесь от всех этих умных указателей.

1