我正在尝试一个小例子来练习继承和多态的概念。这是我的代码的简化版本:
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'
据我所知,在公共继承中,基类的受保护成员成为派生类的受保护成员,并且应该能够像公共成员一样进行访问。这是不正确的?另外,如果长度和宽度是基类的私有成员,那么如何修改代码呢?
答案 0 :(得分:4)
据我所知,在公共继承中,基类的受保护成员成为派生类的受保护成员,并且应该能够像公共成员一样进行访问。这是不正确的吗?
这主要是为真。基类的公共成员和受保护成员可以在派生类中访问(public
继承在这里无关紧要 - 只影响外部观察者的访问权限)。但是,类成员(任何访问权限)只能在自己的类中进行初始化。在这种情况下,只有Shape
可以初始化length
和width
- 它们protected
并不重要,如果它们是{{1}则同样如此}或public
。
您必须添加一个构造函数来执行此操作,您的private
构造函数可以简单地委托给它。无论Rectangle
和length
的访问控制如何,这都有效(只要width
构造函数为Shape
或public
):
protected
或者,为了完整性,您可以只分配它们,但绝对希望struct Shape {
Shape(int l, int w) : length(l), width(w) { }
};
struct Rectangle {
Rectangle(int l, int w) : Shape(l, w) { }
};
初始化它们。此外,这仅适用于相关成员为Shape
或public
:
protected
请注意,您的Rectangle(int l, int w) {
length = l;
width = w;
}
和setWidth()
功能正常 - 您做可以访问setLength()
成员函数中受保护的成员。只是不进行初始化。
答案 1 :(得分:2)
不,基类的受保护成员不会成为派生类的受保护成员。派生类可以访问基类的受保护成员,与私有成员不同,它们在派生类的命名空间中保持受保护(因此同样的事情适用于派生类的派生类,依此类推)
但是基类的受保护成员仍然是基类的成员,基类的构造函数仍然负责构造它们,而不是派生类的构造函数。
答案 2 :(得分:1)
删除部分:长度(l),宽度(w) 如果你想在派生类中使用长度和宽度(继承),你可以只使用它的名称来使用它,例如长度...完成...如果你碰巧有相同的命名字段'长度'然后在派生类中使用派生类' s'长度'使用this-> length ...
当继承时...公共访问说明符声明从基类中公开的公共类在受基类保护的派生类中变得受保护...
使用protected ... public和protected base from protected class