2011-09-08 132 views
0

我正在使用code :: blocks,我認爲gcc。給出的示例代碼(這是僞代碼,並可能無法複製的問題):C++繼承問題

//Assume this is in a separate header file to B 
class TestA 
{ 
    protected: 
     int A; 

    public: 
     void Function1(){A = 0;} 
}; 

class TestB : public TestA 
{ 
    public: 
     void CallFunction(){ A = 10; Function1();}// 
}; 

我會得到類似的編譯錯誤,如: 錯誤:「A」不在此範圍內聲明。 錯誤:Function1()未在此範圍內聲明。

我的印象是所有的基本變量和函數都繼承了子類。鑑於基類有很多函數和變量,我不想使用'using'關鍵字,因爲我必須爲每個函數和變量聲明它(據我所知)。

有什麼辦法讓TestB明確或實際包含它繼承的東西嗎?

有關片段如下

好。這是不可能的,包括示例代碼,因爲它是在項目,但我將引用關鍵片段:

C:\Users\user\Desktop\Projects\RND2\TemplateListAdv.h|30|error: 'Size' was not declared in this scope| 

線,這是對是:

if(!Array.SetToSize(Size)) 

類它在爲:

template<typename TemplateItem> 
class TemplateListAdv : public TemplateList<TemplateItem> 

而且從TemplateList牽連行是:

SIZE_TYPE Size; //SIZE_TYPE is unsigned long. 
//SIZE_TYPE is available in all files as unsigned long. 

文件去: TemplateList.h-> TemplateBasics.h-> TemplateListAdv.h

從我所能看到的沒有丟失的文件。

我會解決它,'使用'關鍵字可以單獨解決它,但這一直在擾亂我,因爲我認爲繼承是自動的。

編譯器數據的要求:

「釋10.05轉6283(2010-05-27 9時09分13秒),GCC 4.4.1的Windows/Unicode的 - 32位」

+1

這應該像預期的那樣工作,所以你必須找到一個例子,它會失敗... – carlpett

+2

嘗試張貼真實的代碼和他們所在的文件。據我可以告訴它只是看起來像你不'在testb.cpp中包含#include「testa.h」 – sashang

+1

發佈出現錯誤的代碼,此代碼沒有錯誤。 –

回答

1

的問題,你」重新訪問類模板訪問基類的東西,是FAQ item

而不是在這裏引用整個FAQ項目,我只是鏈接到它:這是你的答案。

您提供的用於說明問題的代碼無關,對不起。給出一個實際的例子,而不是一個人認爲可能是問題的例子,總是一個好主意。

乾杯&心連心,

+0

謝謝。我會讀到它。 – SSight3

+0

是否有我可以使用的通用'使用'調用? – SSight3

+0

@ SSight3:你可以通過用'this'前綴來將*非依賴*表達式'Size'轉換成*依賴*:this-> Size'告訴編譯器表達式是*依賴*模板參數,然後(* magic發生*:lookup被推遲到實例化,其中基礎也被實例化),它將解決問題。 –

1

的問題是,你正在使用的模板,和基類是「從屬名稱」。也就是說,模板基類可能是專用的,並且沒有Size成員,因爲Size引用不在依賴上下文中,所以編譯器不知道它何時編譯您的類。

在您的特定情況下,最簡單的方法是使用this來指代繼承的成員:

if(!Array.SetToSize(this->Size)) 

而且由於this是一個從屬名稱,它應該工作

1

你肯定:

  • 大小是TemplateList的保護或公共屬性?

  • 你不是從靜態方法調用if(!Array.SetToSize(Size))?

1

這個問題真的很糟糕,你可能想改進一下。無論如何,我的水晶球告訴我,Size定義在基本模板中,並且因爲標識符Size不是,因此查找不會進入基本模板,編譯器也不會看到它。在Size之前添加this->,您應該設置。

+0

改進建議? – SSight3

+0

如果有關於如何改進問題的建議:模板在語言中是非常具體的問題,那麼問題最初包含模板的任何問題應該從那裏開始,在某些情況下它不會相關,但在其他情況下它將會是相關的。不要提供不復制問題的代碼示例,嘗試在較小的測試用例中複製環境中的相同錯誤,它可以幫助您瞭解問題以及它的哪些部分是相關的(在這種情況下,它會有告訴你,刪除模板消除了問題:模板很重要) –

1

當解釋模板成員函數時,編譯器必須(遵循標準)爲每個符號決定它是否依賴於模板參數。如果它依賴於它,那麼只有在實例化模板時纔會解析它。但是,他現在必須解決它。

就你而言,編譯器認爲AFunction1不依賴於模板參數,因此應該在解析後立即解析。你只需要使它取決於使用的模板參數this->Athis->Function1

所以,你應該有這樣的東西。

template < typename T > 
class Base 
{ 
protected: 
    int A; 

public: 
    void Function1() { A = 0; } 
}; 

template < typename T > 
class Derived : public Base<T> 
{ 
public: 
    void CallFunction1() { 
    this->A = 10; 
    this->Function1(); 
    } 
}; 
2

因此,它看起來像你是錯誤的模板類繼承,是不是?與非模板相比,它們有很大的不同。假設你有這樣的代碼:

 

template <class T> 
class TestA 
{ 
    protected: 
     int A; 

    public: 
     void Function1(){A = 0;} 
}; 

template <class T> 
class TestB : public TestA<T> 
{ 
    public: 
     void CallFunction(){ A = 10; Function1();}// 
}; 
 

的問題是由兩階段名稱查找引起的。基種皮類的所有成員都依賴名字,即它們依賴於模板參數T.這是因爲你可以有模板專業化的種皮有完全不同的成員,如:

 

template <class T> 
class TestA 
{ 
    protected: 
     int A; 

    public: 
     void Function1(){A = 0;} 
}; 

template <class T> 
class TestB : public TestA<T> 
{ 
    public: 
     void CallFunction(){ A = 10; Function1();}// 
}; 

template <> 
class TestA<int> 
{ 
}; 
 

現在,在TestA中不是A和Function1成員,所以它們在TestB中也是不可訪問的。爲了讓編譯器知道這些成員確實depende的模板參數,你應該寫TESTB這樣的:

 

template <class T> 
class TestB : public TestA<T> 
{ 
    public: 
     void CallFunction(){ this->A = 10; this->Function1();}// 
}; 
 

這樣,你讓編譯器解析名稱僅在模板實例的時間,而不是模板聲明時,它會以基類成員而聞名。

有一點需要補充的是,VC編譯器沒有這樣的問題,它不嘗試解析模板直到實例化,因此不支持兩階段名稱查找。