class Base {
public:
virtual int f() const {
cout << "Base::f()\n";
return 1;
}
virtual void f(string) const {}
virtual void g() const {}
};
class Derived4 : public Base {
public:
int f(int) const {
cout << "Derived4::f()\n";
return 4;
}
};
int main()
{
string s("hello");
Derived4 d4;
Base& br = d4; // Upcast
// br.f(1); // Derived version unavailable
br.f(); // why does it compile and run?
br.f(s);// why does it compile and run?
}
在派生中:重载基数f()
..因此应隐藏所有基本f()
版本。
现在,对于 br.f()和 br.f(s):由于运行时绑定,派生的f()
和f(s)
应该是调用,但它们应该被隐藏,代码编译并执行int Base :: f()和void Base :: f(string)。
Q1:我缺少什么?
Q2: br.f(1)
无法编译,因为在编译期间,会执行类型检查,并且Base中不存在int f(int)
。我是对的吗?
答案 0 :(得分:1)
基类永远不会知道派生类中新添加的成员,它只有关于成员声明自身的信息
因此,当派生类实例d4
被分配给基类引用br
时,新添加的方法int f(int) const
将隐藏到br
。这就是为什么以下代码的编译错误
// br.f(1); // Derived version unavailable
如下两行成功编译
br.f();
br.f(s);
更多理解:
class Base {
public:
virtual int f() const {
cout << "Base::f()\n";
return 1;
}
virtual void f(string) const {}
virtual void g() const {}
};
class Derived4 : public Base {
public:
int f(int) const {
cout << "Derived4::f()\n";
return 4;
}
void g() const {
cout<< "Derived4::g()" << endl;
}
};
int main()
{
string s("hello");
Derived4 d4;
Base& br = d4; // Upcast
// br.f(1); // Derived version unavailable
br.f(); // No Compilation error
br.f(s);// No Compilation error
d4.f(); // Compilation error
d4.f(s); // Compilation error
d4.f(1); // No Compilation error
d4.g(); // No Compilation error
br.g(); // Will print - "Derived4::g()"
}
希望它有所帮助!
答案 1 :(得分:0)
函数int Derived4::f(int)
隐藏基类中的函数,但不会覆盖它们。为此,它应该具有完全相同的签名。
如果函数覆盖,您可以在基类引用上调用该函数,并查看被调用的派生类函数。