【发布时间】:2016-12-16 22:14:24
【问题描述】:
我有一个类 Base 定义了一个 explicit operator bool:
struct Base {
virtual explicit operator bool() const {
return true;
}
};
我有一个子类Derived,定义了一个operator bool:
struct Derived : Base {
operator bool() const override {
return false;
}
};
如您所见,Derived::operator bool 明确没有标记为explicit,而是标记为override,所以我希望编译器会抱怨。但是,gcc 和 clang 似乎都同意这是有效的。我的期望不合理吗?
此外,如果我使用如下类,TakesBool(base) 不会编译(如预期的那样),但TakesBool(derived) 可以:
void TakesBool(bool b) {}
int main() {
//Base base; TakesBool(base); // compilation error (as expected)
Derived derived; TakesBool(derived);
return 0;
}
这似乎表明Derived 有一个(非explicit)operator bool,但是,它被标记为override 而没有virtual 声明。这怎么可能?
【问题讨论】:
-
关于派生类中不需要
virtual,如果基类已标记为virtual,则它也隐含在所有派生类中。override关键字更多地是对编译器的提示,因此您不要尝试使用不同的签名来覆盖函数(例如在派生类中声明一个函数,该函数采用与基类中的函数不同的参数)。所以这些关键词与问题无关。 -
虚拟调度仍然发生。
Base* pbase = &derived; TakesBool((bool)*pbase);将调用Derived::operator bool。我猜explicit不被认为是函数签名的一部分,所以你可以用非explicit覆盖explicit转换。我不确定这种行为是否正确。 -
这就像在基类中有一个
protected: virtual函数,而在派生类中有一个public: override。一点问题都没有。
标签: c++ c++11 operator-overloading overriding explicit