假设我有两个班级。一个叫Point:
class Point{
public:
Point(): x_(0), y_(0) {}
protected:
int x_, y_;
};
然后我有另一个类,它派生自Point:
class Point3D : public Point {
public:
Point3D(): Point(), z_(0){}
double distance(Point3D pt, Point base) const;
protected:
int z_;
};
double Point3D::distance(Point3D pt, Point base) const
{
int dist_x, dist_y;
dist_x = base.x_ - x_;
dist_y = base.y_ - y_;
return sqrt(dist_x * dist_x +
dist_y * dist_y);
}
然后我得到了如下错误:base.x_在此上下文中受到保护。但Point3D到Point的访问级别是公共的,并且Point中的x_ data成员受到保护。所以它应该没有错误,对吧?有人可以帮我解决这个问题吗?
答案 0 :(得分:6)
但
Point3D
到Point
的访问级别为public
这不完全正确。仅当派生类通过派生类指针/引用访问时,才能访问基类的受保护成员。
double Point3D::distance(Point3D pt, Point base) const
{
int dist_x, dist_y;
dist_x = base.x_ - x_; // x_ is same as this->x_. Hence it is OK.
// base is not a Point3D. Hence base.x_ is not OK.
dist_y = base.y_ - y_;
return sqrt(dist_x * dist_x +
dist_y * dist_y);
}
允许通过基类指针/引用访问基类的protected
成员,这将允许您以导致意外后果的方式更改对象。
说你有:
class Base
{
protected:
int data;
};
class Derived1 : public Base
{
void foo(Base& b)
{
b.data = 10; // Not OK. If this were OK ... what would happen?
}
};
class Derived2 : public Base
{
};
int main()
{
Derived1 d1;
Derived2 d2;
d1.foo(d2);
}
如果
b.data = 10;
在Derived1::foo
中允许,您可以通过d2
修改Derived2
的实例状态Derived1
。这种后门修改不是一种理想的行为。
答案 1 :(得分:1)
公共继承模式只是意味着该对象可以访问其基类的受保护成员。在此示例中,每个Point3D对象只能访问Point3D对象的x_
和y_
成员。
但是,这不允许对象从其基类访问另一个Point的受保护成员。
编辑:正如J. Lin指出的那样,只需将基类型从Point更改为Point3D,即可使成员函数访问x_
和y_
。