包含auto_ptr的对象的std :: vector包含奇怪的行为 [英] std::vector of object containing auto_ptr behaves strangely

查看:252
本文介绍了包含auto_ptr的对象的std :: vector包含奇怪的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Qt库为我的应用程序创建控制面板,并为此创建类
控制

I want to create a control panel for my application using Qt library and for this i create class Controls class

控制:创建一个滑块,并旋转和标签,并以水平布局将它们合并。

Controls : create a slider and spin and a label and orgnize them in horizontal layout .

但是当我想创建 std :: vector< Controls> 程序运行没有错误,但现在控件是创建!因此为什么没有控件。

but when i want to create std::vector<Controls> the program run without error but now controls is creating at all ! so why there is no controls.

Controls.h

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.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析构函数,当我再次运行它时,我得到这个异常

i remove auto_ptr destructor from ~controls , and when i run it again i get this exception

pure virtual method called
terminate called without an active exception




  • 和自动复制构造函数

  • 推荐答案

    这里有两个werid auto_ptr。

    There are two "werid" things here, all related to auto_ptr.

    第一个是成员析构函数只是通过embedder析构函数的出口自动调用。所以显式地销毁meber变量会导致双重破坏,编译器不是设计来管理。

    The first is that members destructors are called automatically just past the exit of the embedder destructor. So explicitly destroy meber variables leads to "double destruction", something the compiler is not designed to manage.

    (注意:一个变量被称为指针不使它变成一个变量:如果使用原始指针,并且调用删除指针不会破坏pointe- r

    (Note: the fact that a variable is called "pointer" will not make it to be anymore a variable: if using raw pointers, and calling delete pointer does not destroy the pointe-r, but the pointe-d, something that auto_ptr do by itself).

    第二个是 auto_ptr 是不可复制的:实际上它使用复制操作符实现移动语义,但...容器(如std :: vector)假定复制是...复制(不移动)。

    The second is that auto_ptr isn't copyable: in fact it uses copy operators to implement move semantics but... containers (like std::vector) assumes that copy is ... copy (not move).

    std :: vector (和std :: list,一个问题,因为实现者注意到了这一点,并避免他们的容器生成同时存在的副本。但是一些mutational算法不能一致地工作,只是因为他们无意中移动到错误的地方 - 将被破坏,只是在函数返回...叹息!)

    In the most of std::vector (and std::list, as well) implementations this is not an issue because the implemetors payed attention to that point and avoid their containers to generate simultaneously existent copies. But some mutational algorithms cannot work consistently, simply because they inadvertently "move" to the wrong place - the one that will be destroyed just after the function return ... sigh!)

    第二个方面通过C ++ 11解决,通过实现支持可复制和可移动元素的容器(C ++ 11配备r值引用,复制和移动是良好的区分操作),并且废除auto_ptr,赞成 unique_ptr ,实现move不是

    This second aspect is solved by C++11, by implementing containers supporting both copyable and movable elements (being C++11 equipped with r-value references, copy and move are well distinguished operations) and deprecating auto_ptr in favor of unique_ptr, that, implement "move" not "above copy" but "instead of copy".

    故事的道德:在C ++ 11中使用 unique_ptr auto_ptr

    Moral of the story: In C++11 use unique_ptr instead of auto_ptr.

    在C ++ 03中,不要在容器或对象中使用 auto_ptr

    In C++03, don't use auto_ptr in containers or in object that have to stay into containers.

    使用原始指针并定义一个正确的(对于你的对象)复制语义(通过做一个深度复制使指针的副本指向对象的副本)语义(通过使指针指向同一个对象,并管理引用计数以触发指向的元素的销毁)boost :: shared_ptr是这种指针的一个例子)

    Use raw pointer and define a proper (for your object) copy semantics (by doing a "deep copy" making copy of pointers to point to copy of objects) or sharing semantics (by making pointer to point to a same objects, and manage reference counting to trigger destruction of the pointed elements. boost::shared_ptr is an example of such a "pointer")

    这篇关于包含auto_ptr的对象的std :: vector包含奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆