简体   繁体   English

混合模板/非模板继承分类和成员继承

[英]Mixed template / non-template inheritance taxonomy and member inheritance

Below is a simple class hierarchy with mix of templatized and non-templatized classes. 下面是一个简单的类层次结构,混合了模板化和非模板化的类。 Embedded in the comments of this example is a compilation error I'm trying to fix. 嵌入在此示例的注释中是我正在尝试修复的编译错误。

I've read a few other related threads here on SO and attempted a few forms of the "using" keyword to no avail. 我已经在SO上阅读了一些其他相关的主题,并尝试了几种形式的“使用”关键字无济于事。

I learned in these trials that: Parent::parent_ivar_ = 99; 我在这些试验中了解到:Parent :: parent_ivar_ = 99; is viable syntax but don't know how to tell the compiler about the inherited ivar grandparent_ivar_ that I'd like to set/use in the Child class. 是可行的语法,但不知道如何告诉编译器我想在Child类中设置/使用的继承的ivar grandparent_ivar_。

Thanks in advance! 提前致谢!

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;
}

There are actually two problems here. 这里实际上有两个问题。

The first problem is that, as it's been noted in another answer, Parent must publicly inherit from GrandParent . 第一个问题是,在另一个答案中已经注意到, Parent必须公开继承自GrandParent

But that's not the only issue. 但这不是唯一的问题。 Even with that fix, this will fail to compile. 即使有了这个修复,这也无法编译。 until Child 's constructor is changed to: 直到Child的构造函数更改为:

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

This is a rather nuanced parsing issue that involves templates. 这是一个涉及模板的相当细微的解析问题。 Until the template is completely parsed, the compiler does not have enough information to know what the heck is grandparent_ivar_ , by itself. 在模板被完全解析之前,编译器没有足够的信息来了解它本身是什么样的grandparent_ivar_ _ivar。 It's not declared in the template class. 它没有在模板类中声明。 It's not some global variable that has been declared previously. 它不是先前声明的一些全局变量。

Until the template is parsed fully, the compiler really can't look at its superclasses, to see what's there. 在完全解析模板之前,编译器实际上无法查看其超类,以查看其中的内容。 Maybe that's where the grandparent_ivar_ is, perhaps. 也许这就是grandparent_ivar_的地方。 Maybe not. 也许不吧。 Who knows. 谁知道。

This is a rough, basic, capsule summary. 这是一个粗略的,基本的胶囊摘要。 The nuts and the bolts of it is that, when declaring templates, you need to give the compiler a bit more slack, and be a bit more explicit. 它的坚果和螺栓是,在声明模板时,你需要给编译器一点松弛,并且更加明确。 There are a couple of ways to do it, but the easiest way is to be more liberal, and explicitly say "this-> foo ", in order to use some foo that might eventually get pulled in from the template's superclass. 有几种方法可以做到这一点,但最简单的方法是更自由,并明确地说“this-> foo ”,以便使用最终可能从模板的超类中拉入的一些foo

Your problem is that Parent privately inherits GrandParent , thus Child cannot see it. 你的问题是Parent私下继承了GrandParent ,因此Child无法看到它。

If Child needs to access GrandParent then you will need to change the inheritance level, or provide a method on Parent (which Child can see) that can be used to change grandparent_ivar_ 如果Child需要访问GrandParent那么您将需要更改继承级别,或者在ParentChild 可以看到)上提供可用于更改grandparent_ivar_

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM