我有一个带有一堆功能的基类和一个扩展该类的派生类,但是基类中有一些方法对派生类没有意义。
是否可以采取措施防止派生类使用这些方法?
Class A
{
...
public:
void SharedMethod();
virtual void OnlyMakesSenseOnA();
}
Class B : public Class A
{
...
public:
void OnlyMakesSenseOnB();
}
以下显然不起作用,但可以做类似的事情,以便编译器不允许调用某个基类方法吗?
Class B : public Class A
{
...
public:
void OnlyMakesSenseOnA() = 0;
}
答案 0 :(得分:4)
这并不像我希望的那样容易回答,但同事建议这种情况表明设计不好,我应该通过添加一个只包含共同点的新基类重新思考我的继承结构功能性:
Class Base
{
...
public:
void SharedMethod();
}
Class A : public Base
{
...
public:
void OnlyMakesSenseOnA();
}
Class B : public Base
{
...
public:
void OnlyMakesSenseOnB();
}
编辑:感谢@David for providing a name我想要破解的规则。 B不是"Behavioural Subtype" of A because it fails the "counterfeit test"。因此,从A派生B违反了Liskov Subtitution Principle。
根据this slide deck,假冒测试如下:
答案 1 :(得分:4)
不,这是完全错误。如果成员函数在派生类型中不可调用,那么您将破坏Liskov替换原则。考虑这是否是正确的继承关系。您可能希望将SharedMethod
提取到真实基础,并提供两种不相关的A
和B
类型。
答案 2 :(得分:2)
如果在派生类上调用了无效方法,您也可以抛出异常。它不会在编译时捕获错误,但至少可以防止它意外地被用作运行时。
Class B : public Base
{
...
public:
void OnlyMakesSenseOnA() { throw Exception(); }
}
答案 3 :(得分:0)
是的,如果我们正在谈论外部呼叫,这是可能的并且非常简单。您可以使用派生类的私有方法隐藏父级的方法。也可以使用静态方法。
在cpp 98、11、14上进行了测试。在C++ shell中尝试一下。
class Base{
public:
void methodBase(){};
static void methodBaseStatic(){};
};
class Derived : public Base{
//private: //(private on default)
void methodBase(){};
static void methodBaseStatic(){};
};
正常操作:
int main()
{
Base b;
b.methodBase();
Base::methodBaseStatic();
Derived d;
return 0;
}
编译错误
int main()
{
Derived d;
d.methodBase();
Derived::methodBaseStatic();
return 0;
}