我有一个抽象的基类,它声明了一个纯虚函数(virtual method() = 0;
)。一些继承的类专门化并使用此方法,但是其中一个继承的类我不想让这个方法可用。我该怎么做?是私人选择吗?
答案 0 :(得分:1)
好吧,你可以扔掉它会使得它更容易被称为。
void method() override { throw /* whatever */ ; }
动态多态是一种运行时属性。因此运行时错误。如果你看一下在编译时会触发的东西,你需要静态多态。
template<typename Child>
struct Parent {
void callMe() {
static_cast<Child*>(this)->callMeImpl();
}
};
struct SomeChild : Parent<SomeChild> {
};
现在,如果您尝试从callMe
扩展的父级调用SomeChild
,则编译时错误。
您也可以像动态多态一样保持指向父级的指针,因为父级将调用子函数
答案 1 :(得分:0)
将私密作为唯一的选择吗?
不,这根本不是一个选择,因为如果它在基类中ENOENT
或public
仍然可以访问该方法。
除了在课堂上实施该方法并诉诸于运行时失败之外,您可以做的事情并不多。你可以将整个东西移植到模板并使用静态多态,在进一步的trickey中,你可以在某些情况下设置编译时失败,但这可能是设计矫枉过正。
答案 2 :(得分:0)
我猜你可以把它变成普通的虚函数而不是像这样的纯虚函数:
virtual void method() { /* code */ }
如果没有在另一个类中使用此函数,您将能够捕获它。例如,你可以警告自己:
virtual void method() { error = true; } //or whatever
答案 3 :(得分:0)
正如其他人所说,在编译时无法执行此操作。如果您指的是指向基类的指针,那么编译器无法知道该指针是否指的是 实现此方法的派生类之一,还是不执行此方法的派生类吨
因此必须在运行时处理该案例。一种选择是抛出异常。另一个选择是引入一个间接级别,以便在调用之前可以询问基类是否实现了某个函数。
假设您有一个Info.plist
课程,其中包含三种方法Base
,foo
和bar
,而某些派生类不希望实施doit
,那么您可以将foo
类拆分为两个基类:
Base
然后,在您当前使用class Base1 {
public:
virtual void foo() = 0;
};
class Base2 {
public:
virtual void bar() = 0;
virtual void doit() = 0;
};
的地方,您改为使用Base
:
BaseSource
如果class BaseSource {
public:
virtual Base1* getBase1() = 0;
virtual Base2* getBase2() = 0;
};
不提供该接口,则getBase1
和getBase2
可以返回nullptr
:
BaseSource