你正在经历“阴影”。成员函数也可以做同样的事情:
#include <iostream>
struct B {
void func() { std::cout << "in base\n"; }
};
struct D : public B {
void func() { std::cout << "in derived\n"; }
};
int main() {
D d;
d.func();
}
http://ideone.com/kjt2Oa
正如其他人所建议的那样,这被称为“阴影”,一个定义隐藏了另一个。
这里要记住的重要一点是静态函数调用是在编译时解决的。因此,以下将具有您预期的行为,但从技术上讲,这是错误的行为,因为它会阻止您在使用基类指针时调用最顶层的“func”:
void callFunc(base* b) {
b->func();
}
int main() {
derived d;
callFunc(&b);
}
因为在调用站点,b->
指向base
并且会调用base::func
而不是derived::func
. 在编译时,编译器只知道 'b' 是base
.
大多数人期望并想要动态行为:
#include <iostream>
struct Animal {
const char* say() { return "???"; }
};
struct Fox : public Animal {
const char* say() { return "A ring ding ding"; }
};
struct Cat : public Animal {
const char* say() { return "Meow"; }
};
void whatDoesItSay(const char* name, Animal* animal) {
std::cout << "The " << name << " says " << animal->say() << ".\n";
}
int main() {
Cat cat;
Fox fox;
whatDoesItSay("cat", &cat);
whatDoesItSay("fox", &fox);
}
http://ideone.com/9wIzq7
这没有所需的行为:
相反,我们需要在基类中使用关键字“virtual”来表示我们想要完全多态的行为,并且我们可以使用新的 C++11 关键字“override”来确保我们正在这样做:
#include <iostream>
struct Animal {
virtual const char* say() { return "???"; }
};
struct Fox : public Animal {
const char* say() override { return "A ring ding ding"; }
};
struct Cat : public Animal {
const char* say() override { return "Meow"; }
};
void whatDoesItSay(const char* name, Animal* animal) {
std::cout << "The " << name << " says " << animal->say() << ".\n";
}
int main() {
Cat cat;
Fox fox;
whatDoesItSay("cat", &cat);
whatDoesItSay("fox", &fox);
}
http://ideone.com/uOtYMv