class base
{
public:
static void func()
{
cout<<"in base class\n";
}
};
class derived: public base
{
public:
void func()
{
cout<<"In derived class\n";
}
};
main() {
derived d;
d.func();
}
如果我在基类中创建一个静态函数并在具有相同名称的派生类中创建一个函数,为什么该函数即使在静态时也会被重新定义?
答案 0 :(得分:2)
它没有重新定义,如果确实如此,由于一个定义规则,您将遇到编译错误。这里有2个函数,一个是成员,一个是static。 d.func()
是成员函数(如.
所示)。另一个函数是base::func()
,它是静态函数(如::
建议的那样)。
答案 1 :(得分:1)
它没有被重新定义,或者你违反了单一定义规则。
你看到的是&#34;范围&#34;:
如果在内部作用域中定义了名称,则会在外部作用域中隐藏(隐藏)同名的所有定义。
您仍然可以使用显式限定来引用外部作用域(基类)中的函数:
base::func
为了将外部范围中的那些添加到重载集,请使用using
- 声明:
using base::func;
如果您这样做,则在使用base::func
时将调用derived::func()
,并在使用derived::func
时调用derivedobject.func()
。
答案 2 :(得分:1)
您正在体验&#34;阴影&#34;。成员函数可以做同样的事情:
#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();
}
这 - 正如其他人所建议的 - 被称为&#34;影子&#34;,一个定义隐藏另一个。
这里要记住的重要一点是静态函数调用在编译时解析。所以下面会有你预期的行为,但从技术上来说这是错误的行为,因为它会阻止你调用最顶层的函数#39;使用基类指针时:
void callFunc(base* b) {
b->func();
}
int main() {
derived d;
callFunc(&b);
}
因为在通话网站上,b->
指向base
并且会拨打base::func
而不是derived::func
。在编译时,所有编译器都知道&#39; b&#39;是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);
}
这没有所需的行为:
相反,我们需要使用关键字&#39;虚拟&#39;在基类中表示我们需要完全多态行为,并且我们可以使用新的C ++ 11关键字&#39; override&#39;确保我们这样做:
#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);
}