【发布时间】:2015-01-30 11:15:11
【问题描述】:
考虑下面的sn-p代码:
#include <iostream>
class A
{
public:
virtual ~A(){}
virtual void saySomething() const
{
std::cout << "Hello from A" << std::endl;
}
};
class B : public A
{
public:
virtual ~B(){}
virtual void saySomething(const std::string& username) const
{
std::cout << "Greetings, " << username << "!" << std::endl;
saySomething();
}
};
class C : public B
{
public:
virtual ~C(){}
void saySomething() const
{
std::cout << "Hello from C" << std::endl;
}
};
int main()
{
C* politeC = new C;
B* politeB = dynamic_cast<B*>(politeC);
politeB->saySomething("User");
return 0;
}
Clang 会给我一个编译器错误提示:
$ clang inheritanceTest.cpp -o InheritanceTestinheritanceTest.cpp:20:9: error: too few arguments to function call, expected 1,
have 0; did you mean 'A::saySomething'?
saySomething();
^~~~~~~~~~~~
A::saySomething
inheritanceTest.cpp:7:18: note: 'A::saySomething' declared here
virtual void saySomething()
^
1 error generated.
但是,如果我确实说 A::saySomething(),那么在 C 中覆盖 saySomething() 将被完全忽略。程序打印输出:
$ ./InheritanceTest
Greetings, User!
Hello from A
奇怪的是,如果我只是将 B::saySomething(const std::string& username) 的名称更改为 B::greetUser(const std::string& username) 那么一切都按预期工作,我得到:
$ ./InheritanceTest
Greetings, User!
Hello from C
这是否意味着不能同时重载和覆盖 C++ 类层次结构中的方法?为什么会这样?为什么编译器不能明确地解析两个重载的函数原型,并在必要时覆盖相应的一个,是否有任何逻辑上的原因?
【问题讨论】:
-
你可以在
saySomething()后面加上override,然后编译器会检查它是否真的是覆盖。
标签: c++