C++ - 访问基 class 的 protected/private 个成员

C++ - Accessing protected/private members of a base class

我正在尝试一个小示例来练习继承和多态性的概念。这是我的代码的简化版本:

class Shape {
protected:
    int length;
    int width;
public:
    virtual void setLength(int l) = 0;
    virtual void setWidth(int w) = 0;
};

class Rectangle : public Shape {
public:
    Rectangle(int l, int w)
    : length(l), width(w)
    { }

    void setWidth(int w) { width = w; }
    void setLength(int l) { length = l; }
};

int main() {
    Rectangle r(0,0);
}

我正在尝试 运行 上面的程序。但是,当我编译 rectangle.cc 时,出现以下错误

g++ -c rectangle.cc

rectangle.cc: In constructor 'Rectangle::Rectangle(int, int)':
rectangle.cc:13:5: error: class 'Rectangle' does not have any field named 'length'
rectangle.cc:13:16: error: class 'Rectangle' does not have any field named 'width'

据我了解,在 public 继承中,基 class 的受保护成员成为派生 class 的受保护成员,并且应该能够像 public 一样访问】 成员。那是不正确的吗?另外,如果 length 和 width 是 base class?

的私有成员,那么代码将如何修改?

不,基 class 的受保护成员不会成为派生 class 的受保护成员。基 class 的受保护成员可由派生 class 访问,与私有成员不同,它们在派生 class 的命名空间中保持受保护(因此同样的事情适用于派生class 的派生 class,依此类推)。

但是基 class 的受保护成员仍然是基 class 的成员,并且基 class 的构造函数仍然负责构造它们,而不是派生 class的构造函数。

To my understanding, in public inheritance, protected members of the base class become protected members of the derived class and should be able to e accessed like public members. Is that incorrect?

这是大部分正确的。 Public 和基 classes 的受保护成员在派生的 classes 中是可访问的(public 继承在这里无关紧要——它只影响外部观察者的访问)。但是,class 成员(任何访问权限)只能在其自己的 class 中 初始化 。在这种情况下,只有 Shape 可以初始化 lengthwidth - 它们是 protected 并不重要,如果它们是 [=12] 也是如此=] 或 private.

您必须添加一个构造函数来执行此操作,您的 Rectangle 构造函数可以简单地委托给它。这与 lengthwidth 的访问控制无关(只要 Shape 构造函数是 publicprotected):

struct Shape {
    Shape(int l, int w) : length(l), width(w) { }
};

struct Rectangle {
    Rectangle(int l, int w) : Shape(l, w) { }
};

或者,为了完整起见,您可以直接分配它们,但绝对更愿意 Shape 初始化它们。此外,这仅在相关成员为 publicprotected:

时有效
Rectangle(int l, int w) {
    length = l;
    width = w;
}

请注意,您的 setWidth()setLength() 函数没有问题 - 您 可以访问 Rectangle 成员中的那些受保护成员职能。只是不用于初始化。

删除部分:长度(l),宽度(w) 如果你想在派生的 class 中使用长度和宽度(继承),你可以通过取它的名字来使用它,例如长度..完成...如果你碰巧在派生class中有相同的命名字段'length'然后使用派生class的'length'使用这个->长度...

当继承... public 访问说明符指出 public 来自基 class 成为派生 class 中的 public 受基 class 受到保护...

当使用 protected...public 和 protected from base class 成为受保护