假设有两个类,如此
class Locator
{
public:
// this goes to the specified latitide and longitude
bool GoToLocation(long lat, long longtd);
};
class HouseLocator : private Locator
{
public:
// this internally uses GoToLocation() after fetching the location from address map
bool GoToAddress(char *p);
}
我使用私有继承来阻止HouseLocator上的GoToLocation(),因为它在那里没有意义,并强迫人们使用正确的接口。
现在我的问题是,我该如何防止这种演员?
HouseLocator *phl = new HouseLocator;
Locator *pl = (Locator*)phl;
pl->GoToLocation(10, 10);
我是否应该记录不要这样做并将其余部分留给用户,我的意思是,如果他做错了演员,这是他的问题?
答案 0 :(得分:6)
使用合成而不是继承:
class Locator
{
public:
bool GoToLocation(long lat, long longtd);
};
class HouseLocator
{
Locator locator_;
public:
// internally uses locator_.GoToLocation()
bool GoToAddress(char *p);
};
如果由于某种原因这不可行,那么使用private
继承就是你最好的选择 - 如果用户将HouseLocator*
投射到Locator*
他们'重新调用未定义的行为,这是他们的问题,而不是你的问题。
答案 1 :(得分:2)
如果您可以更改基类,则可以使用protected
而不是public
来创建函数。
除非告诉人们不这样做,否则你无能为力。
答案 2 :(得分:1)
你做不到。 C cast包含reinterpret_cast功能,您无法阻止任何两种数据指针类型之间的重新解释。
请注意,在某些多重继承的情况下,该强制转换不会进行所需的调整,因此可能无法实现其预期结果。 (static_cast将执行调整,但会检查可访问性)。
答案 3 :(得分:1)
看起来好像HouseLocator
可能不应来自Locator
。在有限的上下文中,您可能需要使用定位器(即,它组成为私有成员变量)。
当您无法直接撰写时(因为您还需要专门化该类),私有继承几乎专门用作合成设备。
通常在需要某种类型的异构集合时使用继承,并且您希望对它们进行相同的处理(或类似情况)。如果你以一种要求你知道派生类型的方式使用派生类,继承实际上通常会损害你的设计,因为它是最紧密的耦合形式(必须构造在一起,不能反弹)。
答案 4 :(得分:0)
不值得试图阻止它恕我直言。用户无论如何都可以Locator* p = new Locator(); p->GoToLocation(10,10);
答案 5 :(得分:0)
您也可以转换运算符
operator Locator() const;
在HouseLocator类中引发异常。但这不会阻止reinterpret_cast<>的转换。什么都不能阻止它。