2016-02-20 153 views
1

下面是一個簡單的類層次結構,其中混合了模板化和非模板化類。嵌入在這個例子的評論是我想解決的編譯錯誤。混合模板/非模板繼承分類和成員繼承

我在這裏閱讀了一些其他相關的線索,並嘗試了幾種形式的「使用」關鍵字無濟於事。

我在這些試驗中瞭解到: 父:: parent_ivar_ = 99; 是可行的語法,但不知道如何告訴編譯器關於我想在Child類中設置/使用的繼承的ivar grandparent_ivar_。

在此先感謝!

class GrandParent { 
public: 
    int grandparent_ivar_; 
}; 

template <typename T> 
class Parent : public GrandParent { 
public: 
    int parent_ivar_; 
}; 

template <typename T> 
class Child : public Parent<T> { 
public: 
    Child() { 
    // The following stmt produces this compiler error using ubuntu g++: 
    // templateinheritance.cpp: In constructor ‘Child<T>::Child()’: 
    // templateinheritance.cpp:20:5: error: ‘grandparent_ivar_’ was 
    // not declared in this scope 
    //  grandparent_ivar_ = 100; 
    // 
    grandparent_ivar_ = 100; 
    } 
}; 

int main(int argc, char *argv[]) { 
    Child<int> c; 
} 

回答

3

實際上有問題在這裏。

第一個問題是,正如在另一個答案中指出的那樣,Parent必須公開地從GrandParent繼承。

但這不是唯一的問題。即使有這種修復,這將無法編譯。直到Child的構造函數改爲:

Child() { 
    this->grandparent_ivar_ = 100; 
    } 

這是一個相當微妙的解析問題,涉及的模板。在模板完全解析之前,編譯器沒有足夠的信息來知道它本身到底是什麼。它沒有在模板類中聲明。這不是先前已經聲明的全局變量。

直到模板完全解析完畢,編譯器才真正看不到它的超類,看看那裏有什麼。也許這就是grandparent_ivar_的地方。也許不會。誰知道。

這是一個粗略的基本膠囊摘要。堅果和它的螺栓是,當聲明模板時,你需要給編譯器一點點鬆懈,並且更加明確一些。有幾種方法可以做到這一點,但最簡單的方法是更寬鬆,並明確地說「this->foo」,以便使用一些foo,最終可能會從模板的超類中拉入。

+0

謝謝你的好信息山姆。是的,我錯過了這個例子中的公共繼承。我認爲這與問題沒有密切關係。我會研究這個 - > foo解決方案。隨着一些進一步的調查「使用GrandParent :: grandparent_ivar;」放置在子類聲明中也起作用。乾杯。 – user501138

0

您的問題是Parent私下繼承GrandParent,從而Child無法看到它。

如果Child需要訪問GrandParent,那麼你將需要更改繼承級別,或Parent提供一個方法(Child可以看到),可以用來改變grandparent_ivar_

+0

對,對不起。我不打算私下繼承GrandParent。這是我原來的例子中的一個疏忽。我修正了這個例子來保留我的問題的重點。 – user501138