模板Subclass-of-Class中的C ++名称解析

时间:2017-03-16 16:05:46

标签: c++ data-members

我试图在不使用“this”指针的情况下访问C ++代码中的基类数据。我的类是模板化的,ClassAClassB的基类,它是ClassC的基类。所有类都是从其基类公开派生的。我发现这个讨论让我想到了解决方案的一半,但并没有完全解决它:

Why do I have to access template base class members through the this pointer?

该页面表明我应该能够使用“using”语句修复我的问题。这是我想要做的一个例子:

#include <iostream>

template <typename FP>
class ClassA
{
    protected:
    FP a ;
} ;

template <typename FP>
class ClassB : public ClassA <FP>
{
    using ClassA <FP> :: a ;
    public:
    void fooB ( void ) { std:: cout << a << std::endl ; }
} ;

template <typename FP>
class ClassC : public ClassB <FP>
{
    using ClassA <FP> :: a ;
    public:
    void fooC ( void ) { std:: cout << a << std::endl ; }
} ;

int main ( int argc, char *argv[] ) 
{
    ClassB <double> tempB ;
    ClassC <double> tempC ;

    tempB.fooB ( ) ;
    tempC.fooC ( ) ;

    return 0 ;
}

上面的代码无法编译,给出以下错误:

stepTWO.cpp: In instantiation of ‘class ClassC<double>’:
stepTWO.cpp:30:25:   required from here
stepTWO.cpp:8:12: error: ‘double ClassA<double>::a’ is protected
         FP a ;
            ^
 stepTWO.cpp:20:11: error: within this context
     class ClassC : public ClassB <FP>

我发现“使用”会使变量可以在 ClassB ClassC中访问,但不能同时访问。如果我将using语句放在两个类中,我会得到上面显示的错误。所有继承都是通过公开推导完成的。

有没有人知道使这项工作的解决方案? (除了使用“this”或完全限定的范围名称来访问我的数据元素?)

1 个答案:

答案 0 :(得分:2)

您的问题在于ClassB using ClassA <FP> :: a ;位于班级的私有部分。这意味着派生类将无法访问它。您需要做的是将其放在受保护的部分,例如变量声明为ClassA。这样做你得到:

#include <iostream>

template <typename FP>
class ClassA
{
    protected:
    FP a ;
} ;

template <typename FP>
class ClassB : public ClassA <FP>
{
    protected:
    using ClassA <FP> :: a ; // protected so it can be inherited
    public:
    void fooB ( void ) { std:: cout << a << std::endl ; }
} ;

template <typename FP>
class ClassC : public ClassB <FP>
{
    using ClassA <FP> :: a ;
    public:
    void fooC ( void ) { std:: cout << a << std::endl ; }
} ;

int main ( int argc, char *argv[] ) 
{
    ClassB <double> tempB ;
    ClassC <double> tempC ;

    tempB.fooB ( ) ;
    tempC.fooC ( ) ;

    return 0 ;
}