为什么我不能访问派生构造函数的成员初始化列表中继承的受保护字段?

Rob*_*ert 2 c++ inheritance class

我是 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;
}
Run Code Online (Sandbox Code Playgroud)

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

for*_*818 8

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

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

class Derived : public Base
{
  public:
      Derived(int a, int b) : Base(a, b)  {  }; 
};
Run Code Online (Sandbox Code Playgroud)

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

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

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

int main()
{
    Base b(10,20);
    Derived d(10,20);
}
Run Code Online (Sandbox Code Playgroud)

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