0

Controlsデフォルトのコンストラクターとコピーコンストラクターと他のコンストラクター、および代入演算子を持つクラスがあり、ベクトルを使用してクラスの配列を作成したいと考えています。 ベクトルのサイズを変更すると、オブジェクトが正しく初期化されます。しかし、デフォルト以外のコンストラクターを使用してオブジェクトを作成したい場合、このエラーが発生します。

アクティブな例外なしで呼び出された終了と呼ばれる純粋仮想メソッド

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


};

コントロール.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

4 に答える 4

0

コピー セマンティクスを正しく実装しているかどうかはわかりません。std::auto_ptrデータ メンバーとしての の使用は一種の「警告サイン」です。

Controls本当にディープコピー可能ですか?

たぶん、データメンバーscoped_ptrの代わりに使用し、プライベートコピーコンストラクターとプライベートauto_ptrを宣言するコピーを禁止し、使用する必要がありますか? operator=vector<shared_ptr<Controls>>

(または、C++11 とムーブ セマンティクスを使用して、unique_ptr代わりに をauto_ptr使用し、コンパイラが自動的に生成したムーブ操作を使用しますか?)

于 2012-10-18T11:04:35.520 に答える
0

std::vectorこれは、デフォルト以外のコンストラクターとは関係ありません。コード全体を提供していただけませんでしたが、これは前の質問の続きだと思います。

あなたControls::operator=は無効です。 のコピーを作成しQWidgets、それらを真新しい に入れますQLayoutControlsあなたが渡すpush_backオブジェクトは、呼び出し後に破棄される一時オブジェクトであり、そのコピーはベクターに入れられます。ただし、破棄されたオブジェクトのQWidgetメンバーはQLayout、破棄されず、表示しようとしているウィジェットに追加される ( Panel) に配置されます。一時Controlsオブジェクトが破棄された後、既に削除されたウィジェットにアクセスしようとするPanel->show()Panel のメソッドを呼び出します。QLayout

オブジェクトのコピーControlsベクトルに保存する必要は本当にありますか? ポインターを保存すると、問題が解決します。なぜそのベクトルが必要なのですか?

もう一度言いますが、 は使用しないauto_ptrでください。これは推奨されておらず、 の削除を正しく管理するためには必要ありませんQObjects

于 2012-10-18T11:06:59.443 に答える
0

また、問題は auto_ptr 変数にあると思います。オブジェクトポインタをどのように扱いたいか、それが本当に正しいかどうかを確認する必要があります。私はむしろ、shared_ptr または unique_ptr に固執したいと思います。ただし、後者の場合、ポインターの所有者は 1 人しかいない可能性があるため、コピー コンストラクターはまったく必要ありません。

C++ std::auto_ptr コピー コンストラクター

于 2012-10-18T11:02:53.750 に答える
0

使用するときは、ポインターを新しい所有者に渡さないように使用auto_ptrする必要があります。releaseget

これではありませんControls::Controls(QLayout &Parent , string name , const int &Default_value):

Layout.addWidget(Label.get() , 0 , 0);

でもあの:

Layout.addWidget(Label.release() , 0 , 0);

それ以外の場合 -auto_ptrこのコンストラクターのスコープの最後にあるポインターを削除しています。

于 2012-10-18T11:10:58.413 に答える