vector :: push_back <myclass>不适用于非默认构造函数</myclass>

时间:2012-10-18 10:48:23

标签: c++ qt

我有一个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 &copy);
    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 &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() ) ;

    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 &copy)
{
    *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 

4 个答案:

答案 0 :(得分:0)

另外,我认为问题出在你的auto_ptr变量上。您应该检查它是否真的是您想要处理对象指针的方式。我宁愿坚持使用shared_ptr或unique_ptr。但是在后一种情况下,您根本不想拥有复制构​​造函数,因为指针只能有一个所有者。

C++ std::auto_ptr copy constructor

答案 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正在删除此构造函数范围末尾的指针。