C++继承问题

发布于 2024-12-03 07:04:12 字数 1339 浏览 1 评论 0原文

我正在使用 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:\Users\user\Desktop\Projects\RND2\TemplateListAdv.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.

Files go: 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 bit”

I am using code::blocks, with, I believe gcc. Given the example code (this is pseudo code and may not replicate the problem):

//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();}//
};

I would get similar compile errors, like:
Error: 'A' not declared in this scope.
Error: Function1() not declared in this scope.

I was under the impression that all base variables and functions were inherited to the subclass. Given the base class has a lot of functions and variables, I don't want to use the 'using' keyword as I'd have to declare it for every function and variable (to my knowledge).

Is there any way to make it so TestB explicitly or actually includes the stuff it's inheriting?

Relevant snippets below

Okay. It's not possible to include example code as it's in project, but I will quote the key snippets:

C:\Users\user\Desktop\Projects\RND2\TemplateListAdv.h|30|error: 'Size' was not declared in this scope|

The line this is on is:

if(!Array.SetToSize(Size))

The class it's in is:

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

And the incriminating line from TemplateList is:

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

Files go:
TemplateList.h->TemplateBasics.h->TemplateListAdv.h

No missing files from what I can see.

I will tack in, the 'using' keyword resolves it individually, but this has been bugging me as I thought inheritance was automatic.

Compiler data as requested:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

柒夜笙歌凉 2024-12-10 07:04:12

所以看起来您在模板类继承中遇到了错误,不是吗?与非模板相比,它们有很大差异。假设您有这样的代码:


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 编译器不存在这样的问题,它在实例化之前不会尝试解析模板,因此不支持两阶段名称查找。

So it looks like you are getting error wite template classes inheritance, isn't it? They are a big difference comparing to non-template ones. Assuming you have code like this:


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();}//
};

The issue is caused by two-phase name lookup. All members of the base TestA class are dependent names, i.e. they depend on the template argument T. This is so because you can have template specialization for TestA with totally different members, e.g.:


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

Now, there is no A and Function1 members in the TestA, so they would be unaccessible in TestB as well. In order to let compiler know that these members are indeed depende on the template argument you should write TestB like this:


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

This way you make compiler resolve names only during template instantiation time instead of template declaration time and it will known about base class members.

One thing to add is that there is no such issue with VC compiler, it doesn't try to parse templates until instantiation and thus don't support two-phase name lookup.

倒带 2024-12-10 07:04:12

您在访问类模板中的基类内容时遇到的问题是常见问题解答项

我没有在这里引用整个常见问题解答项目,而是直接链接到它:这就是您的答案。

抱歉,您提供的用于说明问题的代码是无关的。给出一个实际的例子而不是一个人们认为可能存在问题的例子总是一个好主意。

干杯&呵呵,,

The problem that you're having about accessing base class stuff in a class template, is a FAQ item.

Rather then quoting the whole FAQ item here, I just link to it: that's your answer.

The code that you presented to illustrate the problem was unrelated, sorry. It is always a good idea to give an actual example rather than an example of what one thinks might be the problem.

Cheers & hth.,

禾厶谷欠 2024-12-10 07:04:12

问题是您正在使用模板,而基类是“从属名称”。也就是说,模板基类可以是专门的,并且没有 Size 成员,编译器只是不知道何时编译您的类,因为 Size 引用不在依赖上下文中。

在您的特定情况下,最简单的解决方案是使用 this 引用继承的成员:

if(!Array.SetToSize(this->Size))

并且由于 this 是依赖名称,因此它应该可以工作

The problem is that you are using templates, and the base class is a 'dependent name'. That is, the template base class could be specialized and not have the Size member, the compiler just doesn't know when it compiles your class, because the Size reference is not in a dependent context.

In your particular case the easiest solution is to refer to the inherited members using this:

if(!Array.SetToSize(this->Size))

And since this is a dependent name, it should work

勿忘初心 2024-12-10 07:04:12

您确定:

  • Size 是 TemplateList 的受保护属性还是公共属性吗?

  • 您不是从静态方法调用 if(!Array.SetToSize(Size)) 吗?

Are you sure that :

  • Size is a protected or public attribute of TemplateList ?

  • you're not calling if(!Array.SetToSize(Size)) from a static method ?

嘿看小鸭子会跑 2024-12-10 07:04:12

这个问题确实很糟糕,你可能想改进一下。无论如何,我的水晶球告诉我 Size 是在基本模板中定义的,并且由于标识符 Size依赖,因此查找不会进行进入基本模板,但编译器看不到它。在 Size 之前添加 this-> 即可设置。

The question is really bad, and you might want to improve on that. Anyway, my crystal ball tells me that Size is defined in a base template, and that because the identifier Size is not dependent lookup is not going into the base template and the compiler not seeing it. Add a this-> before Size and you should be set.

帝王念 2024-12-10 07:04:12

当解释模板成员函数时,编译器必须(遵循标准)决定每个符号是否依赖于模板参数。如果它依赖于它,那么只有在实例化模板时才会解决它。不过,此刻他必须解决。

在您的情况下,编译器认为 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();
  }
};

When interpreting a template member function, the compiler must (following the standard) decide for each symbol if it is dependent on the template parameter. If it is dependent on it, then it'll only be resolved when the template is instantiated. However, he must resolve it at this moment.

In your case, the compiler think that A and Function1 don't depend on the template parameter and should thus be resolvable just after the parse. You just have to make it depend on the template parameter by using this->A and this->Function1

So, you should have something like that.

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();
  }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文