2017-02-11 40 views
1

在我的頭腦裏/在紙上進行了很多迭代,我不確定究竟是什麼「最佳」或「最正確」的方法來處理這種情況。在C++中從基類訪問子數據

設置:

  • 我有一個類 'A' 提供給我。我無法改變這堂課。這個類有幾個公共方法。
  • 我已經寫了一個類'B',它接受許多類'A'並將它們作爲一個控件,使用相同的方法名使A和B在代碼中可以互換。
  • 我現在想編寫一個類'C',它可以接受一個類'A'或類'B'(或將來使用相同公共方法的另一個類)來執行更復雜的操作。

我試圖通過編寫一個「超類」'D'來執行通用操作,而'C'可以繼承'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