2016-02-20 150 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