C++-访问基类的受保护/私有成员

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

本文关键字:成员 受保护 访问 基类 C++-      更新时间:2023-10-16

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

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继承在这里并不重要,它只影响外部观察者的访问)。但是,类成员(任何访问权限)只能在自己的类中初始化。在这种情况下,只有Shape可以初始化lengthwidth——它们是protected并不重要,如果它们是publicprivate也是如此。

您必须添加一个构造函数来完成此操作,您的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)如果你想在派生类中使用长度和宽度(继承的),你只需取其名称即可使用,例如length。。完成。。。如果u恰好在派生类中具有相同的命名字段"length",那么要使用派生类的"length。。。

继承时。。。public访问说明符声明public from base class在派生类中变成public protected from base class变成protected。。。

使用受保护的。。。public和protected from base class变为protected