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

Q_A*_*Q_A 5 c++ polymorphism inheritance private protected

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

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

我正在尝试运行上面的程序。但是,当我编译矩形.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'
Run Code Online (Sandbox Code Playgroud)

据我了解,在公共继承中,基类的受保护成员成为派生类的受保护成员,并且应该能够像公共成员一样进行访问。这是不正确的吗?另外,如果长度和宽度是基类的私有成员,那么需要如何修改代码?

Bar*_*rry 6

据我了解,在公共继承中,基类的受保护成员成为派生类的受保护成员,并且应该能够像公共成员一样进行访问。这是不正确的吗?

基本上是正确的。基类的公共和受保护成员可以在派生类中访问(public继承在这里并不重要 - 只会影响外部观察者的访问)。但是,(任何访问的)类成员只能在它们自己的类中初始化。在这种情况下,只能Shape初始化lengthand width- 它们是 并不重要,如果它们是或protected也是如此。publicprivate

您必须添加一个构造函数来执行此操作,您的Rectangle构造函数可以简单地委托给它。length无论and的访问控制如何,这都有效width(只要Shape构造函数是publicor protected):

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

struct Rectangle {
    Rectangle(int l, int w) : Shape(l, w) { }
};
Run Code Online (Sandbox Code Playgroud)

或者,为了完整起见,您可以只分配它们,但绝对更喜欢初始化Shape它们。此外,这仅在相关成员是public以下情况时有效protected

Rectangle(int l, int w) {
    length = l;
    width = w;
}
Run Code Online (Sandbox Code Playgroud)

请注意,您的setWidth()setLength()函数都很好 - 您确实可以访问 的Rectangle成员函数中的受保护成员。只是不用于初始化。