2017-02-11 5 views
1

私の頭の中/紙の中で多くの繰り返しを繰り返しましたが、このシナリオに関して「最良の」または「最も正しい」方法がわかりません。C++の基底クラスから子データにアクセスする

セットアップ:

  • 私が私に与えられたクラス 'A' を持っています。私はこのクラスを変更することはできません。このクラスにはいくつかのパブリックメソッドがあります。
  • 私は多くのクラス 'A'をとり、同じメソッド名を使用してコード内でAとBを交換可能にする 'B'クラスを作成しました。
  • より複雑な操作を実行するために、クラス 'A'またはクラス 'B'(または同じパブリックメソッドで将来他のクラス)をとることができるクラス 'C'を作成したいと考えています。

「C」は「D」を継承し、必要な可変型を提供することができるのに対し、「スーパークラス」は「D」を使用して共通の操作を行うようにしました。しかし、 'D'は 'C'個の変数を見ることができません。

私はこの構造が間違っていると思っているので、ここで適切に継承を使用する方法を汚しています。クラスDにクラスCの型を知らせて、それを強制的にキャストすることはできません。 Dには 'o'の使用を必要とする多くの機能がありますが、潜在的なクラスタイプごとにそれぞれを再実装する必要がありません。

また、私は、これは一般的な問題であると確信しているが、私は2日間の答えを探してきた今...

簡体コード例:

// Class A has been provided to me, and cannot be modified. 
#include <classA.h> 

class B { 
    public: 
    B(A *x, int num): z(x), n(num) {}; 

    int num(void) {return n;}; 
    // Other methods to operate on objects of class A as if they were a single 
    // one, using same method names. Maybe somehow inheritance is better here? 

    private: 
    A *z; 
    int n; 
}; 


class D { 
    public: 
    D(void): s(5) {}; 

    // 'o' to be provided by child class, must have method 'num' 
    void doThat(void) {return s+o.num();}; 

    private: 
    int s; 
}; 

// So we can handle multiple types of devices that have the same public methods 
// This is just a class to get the private object that superclass D will need 
class C: public D { 
    public: 
    C(B *h): o(h) {}; 

    private: 
    B *o; 
}; 

A ar[2] = { A(1), A(2) }; 
B l(ar, 2); 
C j(&l); 

これは私を取得'o'は範囲外です。

Arduino: 1.8.1 (Windows 10), Board: "Arduino/Genuino Uno" 
sketch_feb11b.ino: In member function 'void D::doThat()': 
sketch_feb11b:26: error: 'o' was not declared in this scope 
    void doThat(void) {return s+o.num();}; 
exit status 1 
'o' was not declared in this scope 

私は多くの多くの年後に、新たに戻ってC++にので、私はまた、私は今最初の場所で正しく問題に近づいていないよ受け入れても同じように喜びました。

+0

ためのテンプレートを使用することができます。 [mcve]を作ってください。 – nwp

+0

あなたの[ここにあなたの質問に対するすべての回答](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)があります。 –

答えて

4

あなたはあまりにも多くの詳細を残しD

template<typename T> 
class D: 
{ 
    D(const T* t): m_t(t) {}; 
    int doThat(void) { return m_t->num(); }; 

private: 
    T* m_t; 
} 

A ar[2] = { A(1), A(2) }; 
B l(ar, 2); 
C<B> j(&l); 
+1

この場合、テンプレートは欠落していました。私がC++で働いてからずっとずっとずっと、私はそれらについてすべて忘れていたでしょう。パーフェクトな例あなたが抱えている問題のように思えるものは、あなたが持つ問題ではありません。ありがとう! –

0
class D { 
public: 
    D(): s(5) {} 
    // Your child class must overload getter method getNum() 
    int doThat() { 
    return s + getNum(); 
    } 
private: 
    int s; 
    // pure virtual, must be overload 
    virtual int getNum() = 0; 
... 
}; 

class C : public D { 
private: 
    B* o; 
    // overload pure func 
    int getNum() override { 
    return o->num(); 
    } 
public: 
    // Use default D ctor 
    C(B* b) : D(), o(b) {} 
... 
}; 

A ar[2] = { A(1), A(2) }; 
B l(ar, 2); 
C j(&l); 
j.doThat(); // return 5 + ar->num 
関連する問題