假设我们有两个类,Base
和Derive
。有两个方法,getX
和setX
,它们是公共的,使用受保护的intx
与用户交互。Base
构造将x
设置为1,Derive
构造将x设置为3。
class Base {
public:
Base();
int getX();
void setX(int n);
protected:
int x;
}
int Base::getX() {
return x;
}
void Base::setX(int n) {
x = n;
}
Base::Base() : x(1) {
}
class Derived : public Base {
public:
Derived();
}
Derived::Derived() : x(3) {
}
Derive
类可以完全访问Base中的方法。太好了。
假设出于某种原因,我不希望setX
可供Derive
类的用户使用。我想到了几种方法。
1)在Derive
中将setX
重新声明为私有,因此隐藏会阻止用户完全访问该方法。
2)将x
重新声明为Derive
中的私有const int。但是,这会导致setX和getX与Base::x一起工作。
3)让Base::setX成为虚函数,让Derived::setX函数什么都不做。
处理这件事最好的方法是什么?
由于Derive
是从Base
公开派生的,因此您尝试做的事情没有多大意义。您应该使用私有
或保护的
继承,然后在Derive
中仅向您需要的Base
中的方法提供访问权限,而不是提供访问权限。
首先,正如anatelig所观察到的,通过在Derive
类中使其私有来隐藏1)中的setX
方法并不能阻止有人通过强制转换直接在Base
类上调用它。
所以1)只有当你接受这一点时才可以。
否则,如果您只想将Base
类中setX
的实现提供给许多派生类,但不将其公开给Base
或派生类用户。只需使setX
方法在Base
类中受到保护。在这种情况下,您可能还可以将x设为私有,并从派生
构造函数调用setX
方法。
如果你只是想禁止用户的任何实例派生
类调用该对象的setX
方法……但仍然有它在接口中,很明显,你可以像你在3)提出的让它成为一个虚函数在Base和实现它空派生
.
但是在这种情况下,您违背了“is a”的继承格言(显然您的派生类的行为不像基类)。
如果您正在寻找的是禁止此调用的编译错误,您可以重新考虑您的层次结构:
类real_Base;
不实现setX
方法类Base:公共real_Base;
实现setX
方法类派生:公共real_Base;
不实现setX
方法在这种情况下,那么:
setX
时,您可以使用real_Base
作为接口。setX
时使用Base
setX
时使用Derive
。
您没有覆盖任何虚函数,因此继承是可疑的。
您希望用户使用Base
接口还是Derive
接口?如果你说Derive
,那也是可疑的。
撰写从
并给它一个更好的名称:Base
派生
class Composite {
private:
Base base;
public:
Composite() : base(3) {
}
};