假设我们有两个类Base
和Derived
。有两种方法getX
和setX
,它们是公共的,并使用受保护的int x
与用户进行交互。 Base
构建集x
为1,Derived
构造集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) {
}
Derived
类可以完全访问Base中的方法。大。
我们假设由于某种原因,我不希望setX
类的用户可以使用Derived
。我有几种方法可以做到这一点。
1)在setX
中将Derived
重新声明为私有,因此遮蔽会阻止用户完全访问该方法。
2)在x
中将Derived
重新声明为私有const int。但是,这会导致setX和getX与Base :: x一起使用。
3)使Base :: setX成为一个虚函数,制作一个什么都不做的Derived :: setX函数。
处理此问题的最佳方法是什么?
答案 0 :(得分:5)
由于Derived
公开来自Base
,您尝试做的事情没有多大意义。您应该使用private
或protected
继承,然后仅在Derived
中提供您需要的Base
方法,而不是方法。
答案 1 :(得分:2)
首先,正如anatolyg所观察到的那样,1)中的setX
方法通过在Derived
类中将其设为私有而不会阻止某人通过强制转换直接在Base
类上调用它。
所以1)只有你接受这个才行。
否则,如果您只想在setX
类中为许多派生类提供Base
的实现,但不要将其公开给Base
或派生类用户。只需在setX
类中保护Base
方法。在这种情况下,您可能也可以使x private,并从setX
构造函数调用Derived
方法。
如果你只想禁止任何Derived
类实例的用户在该对象上调用setX
方法......但仍然在界面中显示它,显然你可以像你提议的那样3)使其成为Base中的虚函数,并在Derived
中将其实现为空。
但在这种情况下,你违背了“is a”的继承格言(显然你的派生类的行为与Base类不同)。
如果您要查看的是编译错误,请禁止此通话, 也许你可以重新思考你的等级制度:
class real_Base;
未实现setX
方法class Base : public real_Base;
方法的setX
class Derived : public real_Base;
未实现setX
方法在这种情况下:
real_Base
时,您将使用setX
作为界面。Base
时使用setX
Derived
时使用setX
。答案 2 :(得分:1)
你没有覆盖任何虚函数,所以继承是可疑的。
您是否希望用户使用Base
界面或Derived
界面?如果你说Derived
,那又是可疑的。
从Derived
撰写Base
并给它一个更好的名字:
class Composite {
private:
Base base;
public:
Composite() : base(3) {
}
};
答案 3 :(得分:0)
您无法在x
的初始值设定项列表中初始化成员Derived
,因为x
不是Derived
的成员。您的编译器应该发出错误。