2015-06-25 51 views
2

我有兩個類,有一些名稱相同的方法。 我可以創建第三個類,接受來自另一個兩個ony的引用,並在構造函數中將obj變量設置爲A或B類型?類參考另外兩個類

class A 
{ 
    public: 
     A();   
     void f(); 
}; 

class B 
{ 
    public: 
     B();   
     void f(); 
}; 

class C 
{ 
    public: 
     C(B&); 
     C(A&); 

    ??? obj; 
}; 
+0

是的,但你怎麼做取決於這些類代表什麼以及你如何使用它們。 「C」應該有編譯時決定的'A'還是'B'成員?在這種情況下,使用模板。 A'和'B'是否表示共同行爲的特殊實現?然後創建一個基類並使用繼承和虛函數。 – TartanLlama

+0

如果'A'和'B'的子類都是'X',那麼你可以聲明'obj'爲'X' – Cyclonecode

+0

[Boost變種]怎麼樣(http://www.boost.org/doc/libs/ 1_58_0/DOC/HTML/variant.html)? –

回答

5

也許你想要一個模板類:

template <typename T> 
class C 
{ 
    T& obj; 
    public: 
     explicit C(T& t) : obj(t) {} 
     void f() { obj.f(); } 
}; 

然後:

A a; 
B b; 
C<A> c1(a); 
C<B> c2(b); 
c1.f(); 
c2.f(); 
+1

這就像一個魅力。 :) – selfbg

+0

@selfbg這是C++模板的工作原理。 C++模板提供了編譯時多態性。 – songyuanyao

2

C++是一種非常靈活的語言,因此提供了你所要求的多種選擇。每個人都有自己的優點和缺點。

想到的第一條路線是使用多態性。 您有兩條路徑可供選擇:靜態或動態多態。

靜態多態路由

使用靜態多態性(也被稱爲編譯時多態性)你應該讓C模板類:

template <typename T> class C 
{ 
    public: 
     C(T&); 

     T& obj; 
} 

動態多態路線

要使用動態(也稱爲運行時多態),您應該提供一個接口:

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

     virtual void f() = 0; 
} 

其中AB將實施:然後

class A : public Fer 
{ 
    public: 
     A();   
     void f() overide; 
}; 

class B : public Fer 
{ 
    public: 
     B();   
     void f() overide; 
}; 

C會是這樣的:

class C 
{ 
    public: 
     C(Fer&); 

     Fer& obj; 
} 

的變異路線

有各種庫提供可以安全保存任意類型的類。

這些是一些例子:

當使用這樣的類一般需要操作之前轉換回的實際類型的一些方法它。

+0

還有'boost :: variant'路由通常比侵入式接口繼承更好。 – Puppy

0

您可以擁有一個定義所需接口的基類。

class Base 
{ 
    public: 
     Base(); 
     virtual void f(); 
}; 

而且您可以擁有實現接口的派生類。

class A : public Base 
{ 
    public: 
     A(); 
     virtual void f(); 
}; 

class B : public Base 
{ 
    public: 
     B(); 
     virtual void f(); 
}; 

C然後指Base類和實際上可以接受AB類型的對象。

class C 
{ 
    private: 
     Base& base; 

    public: 
     C(Base& b) : base(b) {} 
}; 

那麼它可以很容易地使用。

int main() 
{ 
    B b; 
    C c(b); 
    return 0; 
}