2016-09-21 55 views
4

說我有一個父類Parent和子類Child1Child2具有後實施MyInterface如何從父轉換爲子女學費類的接口

class Parent { 
    public: 
     Parent(); 
     virtual ~Parent(); 
     virtual void MyMethod(); 
} 
class MyInterface { 
    public: 
     virtual ~MyInterface() {} 
     virtual void MyInterfaceMethod() = 0; 
} 
class Child1 : public Parent { 
    public: 
     Child1(); 
     virtual ~Child1(); 
} 
class Child2 : public Parent, MyInterface { 
    public: 
     Child2(); 
     virtual ~Child2(); 
     virtual void MyInterfaceMethod() override; 
} 

而且說我給一個Parent*指針,我想檢查對象是否正在執行MyInterface,如果是,則將其轉換爲MyInterface*

我試圖達到這樣說:

void MyFunction(Parent* p) { 
    MyInterface* i = dynamic_cast<MyInterface*>(p); 
    if (i != 0) 
     DoSomething(); 
    else 
     cout << "Cannot do anything."; 
} 

但我總是等於0,表示這是從來沒有澆鑄成型MyInterface*即使我肯定知道該對象具有良好的類型。

我該怎麼做到這一點?

+0

什麼是多態性? – skypjack

回答

2

Child2private繼承。

由於MyInterface似乎是一個接口,我想你想要public繼承。

class Child2 : public Parent, public MyInterface { } 
//       ~~~~~~  

LIVE(固定其他錯誤)

+1

你確定嗎?這是因爲這些類沒有多態類型,因爲它們缺少一個虛函數。 – Bathsheba

+0

@Bathsheba我相信,差不多。因爲如果'Parent'不是多態類型,OP會得到編譯器錯誤。 OP說「我總是等於0」,所以我想這是一個運行時問題。 (當然,'Parent'應該是多態的。) – songyuanyao

+2

最小化的代碼示例有兩個問題,但這更可能是真實代碼中的問題。具有私有父繼承的 –

1

你的類必須是多態類型dynamic_cast才能正常工作。

實現這一目標的最簡單的方法是在public面積Parent類的添加

virtual ~Parent() = default;

。然後,dynamic_cast將像松雞一樣嗅探您的界面的繼承樹。從MyInterface,除非MyFunction()有權限訪問private基子,dynamic_cast總是會失敗

+0

你會想明確地讓父母構造函數默認,否則它會被隱式刪除。 –

+0

沒有必要將析構函數設置爲默認值來使我的代碼正常工作,但我很想理解這個'= default'的作用? – Sierramike

+0

這是一個C++ 11的東西。谷歌的語法。 – Bathsheba

0

或者,而不是使用dynamic_cast,我們可以使用Visitor Pattern

#include <iostream> 

class MyInterface { 
public: 
    virtual void DoSomething() = 0; 
}; 

class Parent { 
public: 
    virtual ~Parent() = default; 
    virtual void accept(class Visitor& visitor) = 0; 
}; 

class Child1 : public Parent { 
public: 
    virtual void accept(Visitor& visitor); 
}; 

class Child2 : public Parent, public MyInterface { 
public: 
    virtual void accept(Visitor& visitor); 
    virtual void DoSomething(); 
}; 

class Visitor 
{ 
public: 
    void visit(Child1& child); 
    void visit(Child2& child); 
}; 

void Child1::accept(Visitor& visitor) { visitor.visit(*this); } 
void Child2::accept(Visitor& visitor) { visitor.visit(*this); } 
void Child2::DoSomething() { std::cout << "Do something.\n"; } 

void Visitor::visit(Child1& child) { std::cout << "Cannot do anything.\n"; } 
void Visitor::visit(Child2& child) { child.DoSomething(); } 

void MyFunction(Parent& p) { 
    Visitor v; 
    p.accept(v); 
} 

int main() 
{ 
    Child1 c1; 
    Child2 c2; 
    MyFunction(c1); 
    MyFunction(c2); 
} 

輸出:

Cannot do anything.

Do something.