c++继承问题

C++ Inheritance Issue

本文关键字:问题 继承 c++      更新时间:2023-10-16

我使用code::blocks,我相信是gcc。给出示例代码(这是伪代码,可能不会重复这个问题):

//Assume this is in a separate header file to B
class TestA
{
    protected:
        int A;
    public:
        void Function1(){A = 0;}
};
class TestB : public TestA
{
    public:
        void CallFunction(){ A = 10; Function1();}//
};

我会得到类似的编译错误,像:错误:'A'未在此范围内声明。错误:Function1()未在此范围内声明。

我的印象是所有的基变量和函数都继承到子类。鉴于基类有很多函数和变量,我不想使用'using'关键字,因为我必须为每个函数和变量声明它(据我所知)。

是否有办法使TestB显式或实际包含它继承的东西?

下面的相关片段

好吧。不可能包含示例代码,因为它在项目中,但我将引用关键代码片段:

C:UsersuserDesktopProjectsRND2TemplateListAdv.h|30|error: 'Size' was not declared in this scope|

这一行是:

if(!Array.SetToSize(Size))

它所在的类是:

template<typename TemplateItem>
class TemplateListAdv : public TemplateList<TemplateItem>

而TemplateList中的犯罪行是:

SIZE_TYPE Size; //SIZE_TYPE is unsigned long.
//SIZE_TYPE is available in all files as unsigned long.

文件:TemplateList.h -> TemplateBasics.h -> TemplateListAdv.h

在我看来没有文件丢失。

我将加入,'using'关键字单独解决它,但这一直困扰着我,因为我认为继承是自动的。

编译器数据请求:

"Release 10.05 rev 6283 (2010-05-27 09:09:13) gcc 4.4.1 Windows/unicode - 32位"

所以它看起来像你得到错误编写模板类继承,不是吗?与非模板相比,它们有很大的不同。假设你有这样的代码:

<>之前 template <class T> class TestA { protected: int A; public: void Function1(){A = 0;} }; template <class T> class TestB : public TestA<T> { public: void CallFunction(){ A = 10; Function1();}// }; 之前

该问题是由两阶段名称查找引起的。TestA基类的所有成员都是依赖于的名称,也就是说,它们依赖于模板参数t。这是因为你可以用完全不同的成员对TestA进行模板特化,例如:

<>之前 template <class T> class TestA { protected: int A; public: void Function1(){A = 0;} }; template <class T> class TestB : public TestA<T> { public: void CallFunction(){ A = 10; Function1();}// }; template <> class TestA<int> { }; 之前

现在,TestA中没有A和Function1成员,因此它们在TestB中也不可访问。为了让编译器知道这些成员确实依赖于模板实参,你应该这样写TestB:

<>之前 template <class T> class TestB : public TestA<T> { public: void CallFunction(){ this->A = 10; this->Function1();}// }; 之前

通过这种方式,编译器只在模板实例化时而不是在模板声明时解析名称,并且它将知道基类的成员。

需要补充的一点是VC编译器没有这样的问题,它在实例化之前不会尝试解析模板,因此不支持两阶段名称查找。

在类模板中访问基类内容的问题是一个常见问题。

我没有在这里引用整个常见问题解答,我只是链接到它:这就是你的答案。

您用来说明问题的代码是不相关的,对不起。给出一个实际的例子总是一个好主意,而不是一个你认为可能是问题的例子。

干杯,hth。

问题是你正在使用模板,而基类是一个'依赖名称'。也就是说,模板基类可以是专门化的,没有Size成员,编译器只是不知道什么时候编译你的类,因为Size引用不是在一个依赖的上下文中。

在您的特殊情况下,最简单的解决方案是使用this:

引用继承的成员。
if(!Array.SetToSize(this->Size))

由于this是一个依赖名称,它应该工作

你确定:

  • Size是TemplateList的一个受保护的或公共的属性?

  • 你没有从静态方法中调用if(!Array.SetToSize(Size))吗?

这个问题真的很糟糕,你可能需要改进一下。无论如何,我的水晶球告诉我Size是在基本模板中定义的,并且因为标识符Size不是依赖查找,所以不会进入基本模板,编译器也不会看到它。在Size之前添加this->,您应该设置。

在解释模板成员函数时,编译器必须(按照标准)决定每个符号是否依赖于模板形参。如果它依赖于它,那么它只会在模板实例化时被解析。然而,他必须在这个时刻解决这个问题。

在你的例子中,编译器认为AFunction1不依赖于模板参数,因此在解析之后应该可以解析。你只需要通过使用this->Athis->Function1

使它依赖于模板参数

所以,你应该有这样的东西

template < typename T >
class Base
{
protected:
  int A;
public:
  void Function1() { A = 0; }
};
template < typename T >
class Derived : public Base< T >
{
public:
  void CallFunction1() {
    this->A = 10;
    this->Function1();
  }
};