2

我是 OOP 的新手。最近在C++中学习了一些关于继承的知识,一个protected字段不能从类外访问,但是可以在继承类中访问。我的代码有一些问题,我不明白出了什么问题:

class Base
{
protected:
    int x;
    int y;
    int z;
public:
    Base(int a, int b): x(a), y(b) { cout << "Base constructor" << endl; };
    Base(const Base& prev) : x(prev.x), y(prev.y) { cout << "Base copy constructor" << endl; };

    void print_x()
    {
        cout << x << endl;
    }

    void print_y()
    {
        cout << y << endl;
    }

    ~Base() { cout << "Base destructor" << endl; };
};

class Derived : public Base
{
public:
    Derived(int a, int b): x(a), y(b) { cout << "Derived constructor" << endl; };    ////////ERROR : Class 
 'Derived' does not have any fields named 'x' and 'y'
};

int main()
{
    Base* b = new Base(10, 20);
    Derived* d = new Derived(10, 20);
    delete b;
    delete d;
    return 0;
}

如果Derived继承Base,为什么编译器说Derived没有字段xy

4

1 回答 1

8

你可以在 中访问它们Derived,但它们是 的成员,Base不能直接在 的成员初始化列表中进行初始化Derived。如果他们是,这也行不通public。请注意,Base类是在成员初始化之前初始化的Derived

Derived要初始化基础,您可以在的成员初始化列表中调用其构造函数:

class Derived : public Base
{
  public:
      Derived(int a, int b) : Base(a, b)  {  }; 
};

有关更多详细信息,请参见此处:https ://en.cppreference.com/w/cpp/language/constructor

PS:请注意,关于成员初始化列表,与基中的成员也没有区别private。基类的所有成员都是继承的,并在派生的成员初始化之前进行初始化。

您错过了初始化z,并且在您的示例中没有理由使用newand delete。如果您修复上述问题,您将获得与此代码相同的输出:

int main()
{
    Base b(10,20);
    Derived d(10,20);
}

最后但并非最不重要的一点是,如果您打算以Derived多态方式使用,则需要声明Baseas的析构函数virtual

于 2020-11-19T18:45:01.407 回答