2012-02-02 18 views
1

ベースクラスにウィジェットを作成しようとしていますが、私たちが呼び出す派生クラスがタイトルであることによってウィジェット内で変更されるのは唯一のものです。基底クラスの派生クラス値を使用する

class BaseView : public QWidget { 
    Q_OBJECT 
public: 
    explicit BaseView(QWidget *parent = 0); 
protected: 
    QString title; 
    virtual QString getTitle() const { 
     return title; 
    } 

BaseView.cpp:

class DerivedView : public BaseView { 
    Q_OBJECT 
public: 
    explicit DerivedView(QWidget *parent = 0); 
protected: 
    QString getTitle() const { 
     return title; 
    } 

そして、私は "正しい" にタイトルを設定する派生コンストラクタで:派生クラスのヘッダー内の

BaseView::BaseView(QWidget *parent) : QWidget(parent) { 

    title = "test" 
} 

void BaseView::createTopWidget() { 
    QGroupBox *topWidget = new QGroupBox(getTitle()); 
    .... 
} 

ザ・。

DerivedViewを作成してプログラムを実行すると、タイトルはまだ「テスト」です。私はこれをどうやって基本クラスの派生クラスの値を呼び出して取得しますか?

+0

'getTitle'と' getTopWidgetMessage'との関係は何ですか?つまり、 'getTitle'を仮想として定義しますが、決してどこでも呼び出すことはできません - 何がポイントですか? – ildjarn

+0

ああ、彼らは同じであると思われます。この例では名前を変更しましたが、名前を変更するのは忘れてしまいました。 – chikuba

答えて

2

C++を非常に強く把握していない限り、では、コンストラクタで仮想関数を呼び出さないでください。問題は、サブオブジェクトの作成時にオブジェクトの型が派生オブジェクトではなくベースのサブオブジェクトであるため、仮想関数呼び出しが「間違った」関数にディスパッチされるということです。

ベビー例:

struct Base 
{ 
    virtual int foo() { return 8; } 

    Base() { set_something(foo()); } // who're you gonna call? 
}; 
struct Derived 
{ 
    virtual int foo() { return -12; } 
}; 

Derived d; 

今すぐd.Base()ための基本コンストラクタで、呼び出される関数がd.Base::foo()、ないd.Derived::foo()です。

また、タイムベース・クラスのコンストラクタを実行することにより、メンバー変数titleのみ"test"に設定されており、それはまだのみ後のベースのコンストラクタを実行する派生コンストラクタに割り当てによって上書きされていません完了する。

あなたは、コンストラクタで明示的にタイトルを渡すことによって、あなたの問題を解決することができます:

class BaseView : public QWidget 
{ 
public: 
    BaseView(QWidget * parent = 0, QString const & t = "test") 
    : QWidget(parent), title(t) 
    { 
     something.set_title(title); 
    } 

    // ... 
}; 

class DerivedView 
{ 
public: 
    DerivedView(QWidget * parent = 0) 
    : BaseView(parent, "correct") 
    { } 
}; 
+0

大丈夫です。ええ、私は、ベースクラスが非常に簡単に派生クラスのものを得ることができないだろうと思った。しかし、これを行う他の方法はありますか?タイトル文字列はかなり長くなり、私は他のオブジェクトでも同じことをします。私はすべてを作成するベースクラスの考えを落とさなければならないかもしれないと思います。 – chikuba

+0

@chikuba:私の更新を見てください;私はコンストラクタ内のすべての必要な情報を渡し、派生コンストラクタで必要な初期化子を呼び出します。 –

+0

また、私はあなたが誘導ビューのコンストラクタを缶詰めしたことに気付きました。派生したビューに親(別のウィジェット)がある場合は、その親もベースビューに送信されますか?夢のようなウィジェットがベースビューの親になる理由はない。 – chikuba

関連する問題