如何在c ++中阻止这种类型的转换

时间:2011-04-15 08:39:58

标签: c++ inheritance casting

假设有两个类,如此

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);

我是否应该记录不要这样做并将其余部分留给用户,我的意思是,如果他做错了演员,这是他的问题?

6 个答案:

答案 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<>的转换。什么都不能阻止它。