C++ C+中模板类的继承+;

C++ C+中模板类的继承+;,c++,templates,inheritance,C++,Templates,Inheritance,可能重复: 我在模板和继承方面遇到问题。简单地说,我有一个模板类,我想从中继承另一个模板类。我不明白为什么基类的成员在派生类中不可见?虽然没有使用模板,但一切都按预期进行。例如: template <typename T> class Foo { public: T x; T y; void doX(){ x = x+1; } void doY(){y++;} protected: T a; T b; void doA(){a

可能重复:

我在模板和继承方面遇到问题。简单地说,我有一个模板类,我想从中继承另一个模板类。我不明白为什么基类的成员在派生类中不可见?虽然没有使用模板,但一切都按预期进行。例如:

template <typename T>
class Foo
{
public:
    T x;
    T y;
    void doX(){ x = x+1; }
    void doY(){y++;}
protected:
    T a;
    T b;
    void doA(){a++;}
};

template <typename T>
class Bar : public Foo<T>
{
public:
    void doX(){x++; y++;} // ERROR
    void doY(){x++; y++;} // ERROR
    void doA(){a++;b++;}  // ERROR
};
模板
福班
{
公众:
tx;
T y;
void doX(){x=x+1;}
void doY(){y++;}
受保护的:
Tα;
tb;
void doA(){a++;}
};
样板
分类栏:公共食品
{
公众:
void doX(){x++;y++;}//错误
void doY(){x++;y++;}//错误
void doA(){a++;b++;}//错误
};

在派生类函数中编写this->x,this->y,而不是x,y。

这些变量是从属名称(详细信息请阅读),因此您需要使用
this

void doX(){ this->x++; this->y++; } 
通常
此->
不是必需的,因为它是隐式的。但这是必须的。实际上,显式
这个->
告诉编译器在实例化基类时在第二阶段查找名称,因为本例使用两阶段名称查找机制

或者您可以使用基类将其限定为:

template <typename T>
class Bar : public Foo<T>
{
    typedef Foo<T> base; //add this friendly typedef!
public:
    void doX(){  base::x++; base::y++;} 
    //...
};
模板
分类栏:公共食品
{
typedef Foo base;//添加此友好的typedef!
公众:
void doX(){base::x++;base::y++;}
//...
};

在这种情况下,在实例化
base
(这是
Foo
的typedef)之前无法查找名称的事实在我看来变得更加明显(对人而言)。

尝试使用基类范围引用变量:

Foo<T>::x

如果基类依赖于模板参数,则其成员在派生类定义中不直接可用。在模板实例化之前,编译器不知道基类将包含什么,因此它不会从那里查找任何名称

您可以通过限定名称,强制其将名称视为成员:

void doX(){this->x++; Foo<T>::y++;}  // OK: both forms specify that it's a member
void doX(){this->x++;Foo::y++;}//确定:两种形式都指定它是一个成员

使用DevStudio 2005并使用
int
进行实例化,编译效果很好。如何实例化它?基类(
Foo
)的成员在
栏中不可见:
错误:
在此范围内未声明:“线程模型:posix,gcc版本4.6.3(Ubuntu/Linaro 4.6.3-1ubuntu5)”我甚至没有实例化@Skizz:听起来您的编译器没有正确执行两阶段查找-很多编译器过去都会出错,不幸的是,有些编译器仍在广泛使用。@MFontani:Oops!事实上没有。对不起,这是我的仓促。我说在类中,应该在非静态类成员前面加上“this->”是不是错了?即使你写得更多,它也会提高代码的清晰度。@MihaiTodor:在这种情况下,你需要写
这个
,在其他情况下
这个
是隐式的。接受链接。谢谢。我一直建议在C++中使用<代码> -> >代码>。我认为这只是代码可读性的问题。但在这里,似乎是必要的:|@sorush-r:是的。这里需要它。实际上,显式
这->
告诉编译器在实例化基类时在第二阶段查找名称,因为本例使用两阶段名称查找机制。
void doX(){this->x++; Foo<T>::y++;}  // OK: both forms specify that it's a member