2012-10-17 39 views
-1

我想用Qt庫創建爲我的應用控制面板,爲了這個,我創建類 Controls的std :: auto_ptr的包含對象的矢量行爲異常

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(); 

} 

編輯:

i。從除去auto_ptr的析構函數〜控制,並且當我再次運行它此異常

pure virtual method called 
terminate called without an active exception 
  • 我初始化滑塊和旋轉的拷貝構造函數
+7

沒有進一步,很明顯這個程序有未定義的行爲,因爲(在' Controls()')你明確地調用了'auto_ptr'成員的析構函數,然後它們作爲'Controls'的正常破壞的一部分被隱式地銷燬。 – Mankarse

+1

如果使用'auto_ptr',不要在其中放入析構函數。 [規則零](http://rmartinho.github.com/2012/08/15/rule-of-zero.html)。 –

+0

thak你!我刪除了auot_ptr析構函數,並且我的程序拋出了這種叫做 的純虛方法,但沒有激活異常終止調用 – user1728234

回答

3

這裏有兩個「werid」的東西,都與auto_ptr相關。

第一個是成員析構函數自動調用剛過embedder析構函數的出口。所以明確地銷燬meber變量會導致「雙重破壞」,這是編譯器不能管理的東西。

(注:事實上,一個變量被稱爲「指針」不會使之成爲了一個變量:如果使用原始的指針,並調用delete pointer不破壞pointe- [R,但pointe- d,auto_ptr自己做的事情)。

第二個是auto_ptr不可複製:實際上它使用複製操作符來實現移動語義,但是......容器(如std :: vector)假定複製是...複製(不移動)。

在大多數的std::vector(和std ::列表,以及)的實現,這不是一個問題,因爲implemetors祈禱,注意這一點,並避免其集裝箱生成同時存在的副本。但是一些突變算法不能一致地工作,僅僅是因爲它們無意中「移動」到錯誤的地方 - 在函數返回之後就會被銷燬......嘆息!)

第二個方面由C++如圖11所示,通過實現支持可複製和可移動元素(作爲具有r值參考的C++ 11,複製和移動非常明顯的操作)的支持容器,並且棄用auto_ptr而傾向於unique_ptr,即實現「移動」而不是「複製「而是」而不是複製「。

這個故事的:在C++中使用11的unique_ptr代替auto_ptr

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

使用原始指針並定義一個合適的(用於您的對象)複製語義(通過執行「深層複製」將指針的副本指向複製對象的指針)或共享語義(通過使指針指向相同的對象,並且管理引用計數來觸發銷燬指向的元素,boost :: shared_ptr就是這樣一個「指針」的例子)

1

運行的程序沒有錯誤,但現在控制是建立在所有!

那其實是一個很奇怪的,因爲在Controls::Controls(const Controls &copy)你調用this->Slider.get()將返回0,因爲你的成員尚未初始化。

首先,您需要閱讀並瞭解如何使用auto_ptr。其次,你應該忘記auto_ptr,永遠不要再使用它。 Qt有自己的智能指針,但它們不是你需要的,因爲QObject管理他們的孩子的一生。

所以,第三,閱讀關於Qt中的內存管理,並根本擺脫所有這些智能指針。