无法在C ++中继承类模板的第二级访问受保护的类成员

时间:2017-11-20 18:58:48

标签: c++ templates inheritance protected

我在从另一个类模板派生的类模板中访问受保护的类成员时遇到问题。我有三个类模板,第二个派生自第一个,第三个派生自第二个。具体地,

class1.h:

template <typename T> class class1
{
protected:
    T data;
    int a;
public:
    class1();
    void someMethod();
};

class2.h:

#include "class1.h"

template <typename T> class class2: public class1<T>
{
    using class1<T>::a;
    T otherData;
public:
    class2();
};

class3.h:

#include "class2.h"

template <typename T> class class3: public class2<T>
{
    using class2<T>::a;
public:
    class3();
};

class2.cpp:

#include "class2.h"
#include <iostream>

template <typename T> class2<T> :: class2()
{
    std::cout<<"Creating class2 object!"<<std::endl;
    a = 2;
}

template class class2<double>;

最后,class3.cpp:

#include "class3.h"
#include <iostream>

template <typename T> class3<T> :: class3()
{
    std::cout<<"Creating class3 object!"<<std::endl;
    a = 3;
}

template class class3<double>;

当我将class2.cpp编译成目标文件时,如下所示:

g++ -c -O3 -std=c++11 -Wall -o class2.o class2.cpp
一切顺利。但是,以相同的方式编译class3.cpp时会出错。弹出以下错误:

In file included from class2.h:4:0,
                 from class3.h:4,
                 from class3.cpp:1:
class3.h: In instantiation of ‘class class3<double>’:
class3.cpp:11:16:   required from here
class1.h:9:6: error: ‘int class1<double>::a’ is protected
  int a;
      ^

在class3中用using class2<T>::a;替换using class1<T>::a;无济于事。 究竟是什么导致了这个错误,如果我真的需要从class3中访问变量a,我该如何避免呢?为什么第一级继承(class2)没有检测到任何问题,第二级(class3)确实?感谢您的任何意见。

注意:我尝试了相同类型的继承,但是没有模板并删除了包含using的两行,并且编译顺利(现在在class3中授予了对变量a的访问权限)。问题肯定与模板有关。

1 个答案:

答案 0 :(得分:2)

您的cars定义与以下内容相同:

class2

这是因为template <typename T> class class2: public class1<T> { private: // default section using class1<T>::a; T otherData; public: class2(); }; private es成员的默认部分。因此,class成员在此处变为私有,并且无法由a继承。您应该在class3定义的using class1<T>::a;protected部分明确地添加public语句:

class2

现在可以从template <typename T> class class2: public class1<T> { T otherData; protected: // <-- added using class1<T>::a; public: class2(); }; 派生类(包括class2)访问它。