2011-07-13 17 views
1

私の問題を説明するのはかなり難しいです。 私は2つのクラスを持っています、私は​​とDerived_Aと言うでしょう。名前から見ると、クラスDerived_Aは​​から派生しています。また私のプログラムでは、他の2つのクラスBase_BDerived_B(継承もあります)があります。クラス​​はオブジェクトBase_Bを含み、クラスDerived_AはオブジェクトDerived_Bを含む。C++継承ポインタ

class Base_A { 
public: 
    Base_A() {} 
    virtual ~Base_A() {} 

    Base_B b_; 
    Base_B* pointer_; 

    void init() { 
     b_ = Base_B(); 
     pointer_ = &b_; 
     pointer_->setValue(1); 
    } 

    void print() { 
     pointer_->getValue(); 

    } 
}; 

class Derived_A: public Base_A { 
public: 
    Derived_A() {} 
    virtual ~Derived_A() {} 

    Derived_B b_; 
    Derived_B* pointer_; 

    void init() { 
     b_ = Derived_B(); 
     pointer_ = &b_; 
     pointer_->setValue(2); 
     pointer_->increaseValue(); 
    } 
}; 

class Base_B { 
public: 
    Base_B() {} 
    virtual ~Base_B() {} 

    int value_; 

    void setValue(int value) { 
     value_ = value; 
    } 

    void getValue() { 
     cout << "Base_B: " << value_ << endl; 
    } 
}; 

class Derived_B: public Base_B { 
public: 
    Derived_B() {} 
    virtual ~Derived_B() {} 

    void increaseValue() { 
     value_++; 
    } 
}; 

int main() { 
    Derived_A derived_A = Derived_A(); 
    derived_A.init(); 
    derived_A.print(); 

    return 0; 
} 

Aのすべてのクラスをどのように見ることができるかは、クラスBの1つのオブジェクトとこのオブジェクトへのポインタです。私の問題は、私が関数print()を呼び出すと、Derived_B* pointer_を受け取りませんが、存在しないBase_B* pointer_にアクセスしようとしています。私のプログラムでは、クラスに応じてポインタを取るべきだと言うことができますか?それとも私がDerived_Aクラスのような内部Base_B* pointer_をdeclarateする必要があります:

Base::pointer_ = pointer_; 

たぶん、私の問題のための他の方法またはアルゴリズムはありますか?

ありがとうございました。

+0

適切なポインタを返す仮想関数を作成できます。 Derived_Aに2つの 'pointer_'があることをご存知ですか? –

+0

はい、私はDerived_Aに2つのポインタがあることを知っています。それはほんの一例でした。実際のプログラムでは、このポインタの名前は異なります。あなたのアイデアについて。あなたは私にクラスBのポインタを返す関数が必要であり、関数print()にこのポインタを渡すよりも、意味はありますか? –

+0

どちらか、またはそのメソッド呼び出しを直接print()に入れます。また、バーチャルプリントを作成して派生クラスでオーバーライドすることもできます。私はあなたが何をしようとしているのか分かりません。 –

答えて

3

「が、存在していないBase_B* pointer_、アクセスしようとする」DerivedAが正しく、その後DerivedAは継承のための「ISA」ルールと変更設計ニーズを満たしていない、BaseAを初期化していない場合

を。物事の顔に:

  1. は、派生クラスのようなb_pointer_中の名前を再利用しないでください。 それはちょうど混乱し、あなたは価値がありません。
  2. init()を仮想にします。
  3. DerivedA :: init()は、BaseA :: init()を明示的に呼び出します。
  4. ポインタを仮想メソッドにします。

仮想メソッドに "共変戻りタイプ"を使用することに注意してください。

class BaseA 
    { 
    public: 
     virtual BaseB* pointer() { return &b_; } 
     // etc. 
    }; 

class DerivedA : public BaseA 
    { 
    public: 
     virtual DerivedB* pointer() { return &b_; } 
     // etc. 
    }; 
0

Base_A :: init()が呼び出された場合、Base_AにはBase_Bへのポインタがありませんか? なぜ基本クラスを初期化しないのですか?

+0

クラスDerived_Aをinit()したときに、Base_B * pointer_の値をオーバーライドすることについてもっと考えました。同じように私は継承の仮想関数をオーバーライドすることができます。あるいは、ポインタ_が異なるタイプを持つことができるテンプレートを使用することもできます。しかし、私は正確にどのように知りません。 –