2012-12-01 22 views
1

我有以下程序:C++多態性接入來源於基類類字段

#include <iostream> 

class Base {}; 

class Deriv : public Base 
{ 
    public: 
     int data; 
     Deriv(int data): data(data) {} 
}; 

int main() 
{ 
    Base *t = new Deriv(2); 
    std::cout << t->data << std::endl; 
} 

當我編譯它,我得到的錯誤:

x.cpp: In function ‘int main()’: 
x.cpp:15:21: error: ‘class Base’ has no member named ‘data’ 

我如何才能訪問到數據字段(注意,我不想使用Deriv * t = new Deriv(2))?

+4

您必須首先將其轉換爲指定的類型。 – atoMerz

+0

@AtoMerZ,是唯一的方法嗎? – kaspersky

+0

取決於您的要求。你也可以做@ tp1所說的。基地無法瞭解數據。 **你必須以某種方式告訴它。 – atoMerz

回答

1

你已經聲明你的指針的類型是Base並且編譯器是正確的,那個類中沒有成員data。您需要將指針返回到Deriv*才能以此方式訪問該成員。無論如何,你爲什麼要將類型指針指向基類?當你有一個多態的類層次結構時,這通常很有用。

你可以考慮使用一個虛函數來返回這個成員的值,但是不知道你的類和代碼試圖達到什麼樣的目的很難推薦這種或那種方法。基於你的小示例代碼,只需使用

Deriv *t = new Deriv(2); 

代替,似乎是一個更好的選擇

+0

的確,我有一個多態的類層次結構。我用我的問題的一個小例子來指出我的問題。我將使用((Deriv *)t) - >我需要它的數據。 – kaspersky

+0

@ gg.kaspersky哦,我明白了,這從代碼中並不明顯。也許虛擬功能方法是當時的長遠之路。 – mathematician1975

+0

該數據字段僅用於Deriv類。我不想做一個虛擬的getter,並強制所有繼承Base的類來實現它。 – kaspersky

5

將這個基類:

virtual int get_data() const=0; 

然後派生的類將需要實現它 - 所有數據的所有派生類將通過接口:

class Base 
{ 
    virtual int get_data() const = 0; 
}; 

class Deriv: public Base 
{ 
public: 
    int data; 
    Deriv(int data): data(data) {} 
    virtual int get_data() const 
    { return data; } 
}; 
+0

標準解決方案。 +1。你應該提到這也在Base中。 –

+0

也許基地不應該有這個功能。這怎麼能成爲標準? – atoMerz

+0

@AtoMerZ它是標準的,因爲它避免了類切換並引入了適當的接口。 –

2

Object t有類型指針 - 至BaseBase未定義data成員,這就是您的代碼無法編譯的原因。如果你肯定知道tDeriv類型的實際對象(如與您發佈的代碼的情況下),你可以爲了投它可以調用Deriv成員:

Deriv* d = static_cast<Deriv*>(t); 
std::cout << d->data << std::endl; 

如果你沒「知道那tDeriv類型的實際對象,你就需要通過將dynamic_cast到多態垂頭喪氣,並檢查返回值:

Deriv* d = dynamic_cast<Deriv*>(t); 
if (d != nullptr) 
{ 
    std::cout << d->data << std::endl; 
} 

在任何情況下,根據您發佈的代碼,你不」通過將t聲明爲真的獲得任何東西如果您只是使用它來訪問僅由Deriv定義的數據成員。

+3

請注意,dynamic_cast具有合理的運行時間開銷,有時需要編譯時間標誌設置爲在某些編譯器中正常工作。 – Yakk