我有一个Controls
类,它有默认的构造函数和复制构造函数以及其他构造函数,还有一个赋值运算符,我想用vector创建我的类的数组。当我调整矢量大小时,我可以正确初始化对象;但是当我想使用非默认构造函数创建我的对象时,我得到了这个错误,
称为纯虚方法 在没有活动异常的情况下终止调用
Controls.h
class Controls : public QObject
{
private:
QHBoxLayout Layout ;
string Controlname;
std::auto_ptr<QLabel> Label ;
std::auto_ptr<QSlider> Slider ;
std::auto_ptr<QSpinBox> Spin ;
public:
Controls(QLayout &Parent , string name , const int &Default_value);
Controls(const Controls ©);
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() ) ;
Slider->setValue(copy.Get_Slider()->value());
Slider->setOrientation(Qt::Horizontal);
Label->setText(QString ("unamed"));
Spin->setValue(copy.Get_Spin()->value());
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)));
return *this ;
}
Controls::Controls(const Controls ©)
{
*this = copy ;
}
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);
Slider->setOrientation(Qt::Horizontal);
Label->setText(QString (name.c_str()));
Spin->setValue(Default_value);
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 ......
vector <Controls> i ;
i.resize(2 ); // this is work
i.push_back(Controls(layout , "WHITE_BALANCE_RED_V" ,12);// this is not working
答案 0 :(得分:0)
另外,我认为问题出在你的auto_ptr变量上。您应该检查它是否真的是您想要处理对象指针的方式。我宁愿坚持使用shared_ptr或unique_ptr。但是在后一种情况下,您根本不想拥有复制构造函数,因为指针只能有一个所有者。
答案 1 :(得分:0)
我不确定您是否正确实现了复制语义,并且使用std::auto_ptr
作为数据成员是一种“警示标志”。
您的Controls
是否真的可以深入复制?
也许您应该使用scoped_ptr
代替auto_ptr
数据成员,禁止复制声明私有复制构造函数和私有 operator=
,并使用vector<shared_ptr<Controls>>
?
(或者使用C ++ 11并移动语义,所以使用unique_ptr
而不是auto_ptr
,只使用编译器自动生成的移动操作?)
答案 2 :(得分:0)
这与std::vector
和非默认构造函数无关。
您没有提供整个代码,但我认为这是previous question。
您的Controls::operator=
无效,会创建QWidgets
的副本,并将其置于全新的QLayout
中。传递给Controls
的{{1}}对象是在调用后被销毁的临时对象,它的副本被放入向量中。但是被破坏对象的push_back
成员被放入QWidget
,这些成员没有被销毁,而是被添加到您尝试显示的小部件(QLayout
)中。在销毁临时Panel
对象后,Controls
会调用Panel尝试访问已删除小部件的Panel->show()
方法。
您真的需要在向量中保存QLayout
个对象的副本吗?如果你存储指针,那将解决你的问题。为什么你需要那个载体?
再一次,不使用Controls
,它已被弃用,您不需要它来正确管理auto_ptr
的删除。
答案 3 :(得分:0)
使用auto_ptr
时,您应使用release
而不是get
将指针传递给新所有者:
Controls::Controls(QLayout &Parent , string name , const int &Default_value)
中没有这个:
Layout.addWidget(Label.get() , 0 , 0);
但那:
Layout.addWidget(Label.release() , 0 , 0);
否则 - 您的auto_ptr
正在删除此构造函数范围末尾的指针。