【问题标题】:Subclasses failing to inherit superclass fields [duplicate]子类无法继承超类字段[重复]
【发布时间】:2018-07-25 18:02:21
【问题描述】:

我有一个名为 A 的类,其定义如下:

class A {
public:

    int time;
    A *next; 
    someFunc();
    A();
    virtual ~A();
};

我有一个 A 的子类,称为 B,其定义如下:

#include "A.h"

class B : public A {
public:

    int state;
    Foo *ID;
    someFunc();
    B(int time, A *next, int state, Foo *id);
    virtual ~B();
};

B的构造函数定义为:

B::B(int time, A *next, int state, Foo *id) : time(time), next(next), state(state), ID(id) { }

当我构建程序时,我收到一个错误,即 B 类没有名为“time”或“next”的字段。我确保我在 B.h 文件和 B.cpp 文件中都包含了 A.h,但它似乎没有什么不同。值得注意的是,B 类中的 someFunc() 被识别。我在 B.cpp 中定义了一个与 A 类版本不同的主体。在 B.h 的声明中,Eclipse 有一个标记提醒我它“阴影”A::someFunc(),所以我知道 B 至少继承了那个。

我正在 Eclipse 中开发这个程序并使用 makefile 来构建它。我构建 B.o 的路线是:

B.o: B.cpp B.h
    g++ -c -Wall -g B.cpp

我也尝试在第一行末尾添加 A.h,但没有任何作用。我是否遗漏了可能导致此错误的内容?

【问题讨论】:

    标签: c++ class inheritance makefile subclass


    【解决方案1】:

    你不能初始化基类的成员,这应该是基类的责任。

    您可以为A 添加一个初始化此类成员的构造函数:

    class A {
    public:   
        int time;
        A *next; 
        someFunc();
        A();
        virtual ~A();
        A(int time, A* next);
    };
    
    A::A(int time, A *next) : time(time), next(next) { }
    

    然后

    B::B(int time, A *next, int state, Foo *id) : A(time, next), state(state), ID(id) { }
    

    如果不能为A添加构造函数,或者在B的构造函数中赋值:

    B::B(int time, A *next, int state, Foo *id) : state(state), ID(id) {
        this->time = time;
        this->next = next;
    }
    

    【讨论】:

    • 知道了!非常感谢。
    【解决方案2】:

    B 类确实有来自A 的成员。但它们不在构造函数初始化列表的范围内。您必须创建一个 A 构造函数,将您想要传递给 A 的参数:

    class A {
    public:
    
        int time;
        A *next; 
        someFunc();
    
        A(int time, A* next)
            : time(time), next(next)
        {}
    
        virtual ~A();
    };
    
    class B : public A {
    public:
    
        int state;
        Foo *ID;
        someFunc();
    
        B(int time, A *next, int state, Foo *id)
            : A(time, next), ID(id)
        {}
    
        virtual ~B();
    };
    

    【讨论】:

      【解决方案3】:

      一个构造函数初始化列表只能初始化它自己的类成员,不能初始化它的父类成员。您通常想要做的是使用父级的构造函数来初始化它们。

      class A {
      public:
      
          int time;
          A *next; 
          someFunc();
          A(int time, A *next) : time(time), next(next) {}
          virtual ~A();
      };
      
      class B : public A {
      public:
      
          int state;
          Foo *ID;
          someFunc();
          B(int time, A *next, int state, Foo *id) : A(time, next), state(state), ID(ID) {}
          virtual ~B();
      };
      

      【讨论】:

        【解决方案4】:

        您为参数使用了相同的名称,因此它们“隐藏”了成员。你可以在构造函数体中做这样的事情:

        this->time = time;
        this->next = next;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-14
          • 2014-08-29
          • 1970-01-01
          • 1970-01-01
          • 2023-03-23
          相关资源
          最近更新 更多