Я хочу создать панель управления для моего приложения с использованием библиотеки 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 ©);
~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 ©);};
Controls.cpp
Controls &Controls::operator= (const Controls ©)
{
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 ©)
{
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
Здесь есть две «странные» вещи, все связанные с 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 является примером такого «указателя»)
программа запускается без ошибок, но теперь управление создается вообще!
Это на самом деле очень странно, потому что в Controls::Controls(const Controls ©)
ты звонишь this->Slider.get()
который вернет 0, потому что ваши участники еще не инициализированы.
Во-первых, вам нужно прочитать и понять, как использовать auto_ptr
,
Во-вторых, вы должны забыть о auto_ptr
и никогда не используйте его дальше. Qt имеет свои умные указатели, но они не нужны в вашем случае, потому что QObjects управляют жизнью своих детей.
Итак, в-третьих, прочитайте об управлении памятью в Qt и избавьтесь от всех этих умных указателей.