2013-11-09 117 views
-1

我有2類:指向抽象基類的指針需要一些轉換? C++

class MyAbstractClass 
{ 
public: 
virtual const std::string& getStr() const =0; 
} 

class MyRealClass : public MyAbstractClass 
{ 
public: 
virtual const std::string& getStr() const { return m_str;}; 

private: 
std::string m_str; 
} 

我在主:

MyAbstractClass* ptr = new(MyRealClass("some string")); 

我想通過一個指針存儲在MyRealClass基類字符串信息。 我需要投下ptrMyRealClass才能獲取信息嗎?或運行時環境將足夠聰明,以找出我實際上從MyRealClass調用getStr

ptr->getStr(); 或其他類似static_cast<MyRealClass*>(ptr)->getStr();甚至dynamic_cast<MyRealClass*>(ptr)->getStr();

一般來說,如果我們使用的是一個指向Abstract基類的指針,而不僅僅是一個簡單的(真實的)基類,那麼我們是否真的需要進行轉換?

+0

你有沒有嘗試過這些替代方法?有工作嗎?有沒有失敗? –

+0

請在編譯之前編譯您的代碼! –

+0

請注意,您可以刪除'new'語句中的一半括號,它仍然意味着同樣的事情。 –

回答

2

你想要什麼叫做多態性,它是面向對象編程語言(如C++)的一個特性。如果你的方法是虛擬的,你可以在派生類中重寫它們,如果你把它們稱爲虛擬的(如你在例子中用getStr()做的那樣)方法從基類指針它將調用您實例化的類的版本(在您的示例MyRealClass)。如果你沒有將它們標記爲虛擬的,它們將從你有的指針的類型中調用該方法的版本。 (如果你想知道更多關於主題,搜索「虛擬表」,「虛擬調度」和「後期綁定」)

注意,當你寫:

virtual void someMethod() = 0; 

您聲明所謂作爲純粹的虛擬方法,因爲它們沒有自己的實現,所以你不得不在派生類中定義它們(即如何在C++中創建接口和抽象類)。

0

爲了從派生類轉換到基類,可以使用static_cast,儘管編譯器足夠聰明,可以自己完成它(不需要實際執行轉換)。因此,這是不夠的:

MyAbstractClass* ptr = new(MyRealClass("some string")); 

然而,在你的情況,你的基類沒有虛析構函數,什麼刪除,當你是一個未定義的行爲。


如果你想從基礎派生到派生 - static_cast是不夠的。然後你需要使用dynamic_cast,並檢查它是否成功。

0

否;你可以通過抽象類來調用指向抽象基類的子類的成員。儘管您展示的代碼示例不完整。

將虛擬析構函數的接口,爲混凝土類的構造函數,以及清潔一些分號 - 我們得到:現在

#include<string> 

class MyAbstractClass{ 
public: 
    virtual const std::string& getStr() const = 0; 

    virtual ~MyAbstractClass(){} 
}; 

class MyRealClass : public MyAbstractClass{ 
public: 
    MyRealClass(std::string str) : 
    m_str(str) 
    {} 

    virtual const std::string& getStr() const{ 
    return m_str; 
    } 
private: 
    std::string m_str; 
}; 

,呼叫MyAbstractClass* ptr = new MyRealClass("some string");會讓ptr->getStr()回報「一些串」。