考虑以下计划:
class Base {
public:
virtual void foo() const {
cout << "Base::foo()" << endl;
}
};
class Derived : public Base {
public:
virtual void foo() {
cout << "Derived::foo()" << endl;
}
};
void func(Base& obj) {
obj.foo();
}
void main() {
Derived d;
func(d); // Base::foo() is printed
}
Run Code Online (Sandbox Code Playgroud)
如果我const从Base类foo方法中删除然后Derived::foo()调用.我似乎无法理解这种行为.
1)这种行为的原因是什么?
2)这是在编译时还是在运行时决定的?
谢谢
在派生类中,函数签名是这样的:
virtual void foo(); //Derived::foo
Run Code Online (Sandbox Code Playgroud)
哪个没提const.它是一个非const成员函数,而它Base::foo是一个const成员函数.它们是两个不同的函数,因为它const是函数签名的一部分.
virtual void foo() const; //Base::foo
Run Code Online (Sandbox Code Playgroud)
派生类不会覆盖此函数,而是添加另一个函数.
所以修复是这样的:
class Derived : public Base {
public:
virtual void foo() const {
cout << "Derived::foo()" << endl;
}
};
Run Code Online (Sandbox Code Playgroud)
作为const功能签名的一部分.因此,当你打算覆盖base的foo时,你必须提到它.
@ davka的问道:
为什么选择const版本而非const?是否有任何规则或者恰好是第一个选择?
它因为静态类型obj是Base,而函数名是根据对象的静态类型来解析的.Base甚至没有非const版本.所以毫无疑问它被选中或被拒绝.它始终不存在Base.
void func(Base& obj) {
obj.foo(); //calls Base::foo
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您将上面的代码更改为以下代码:
void func(Derived & obj) {
obj.foo(); //calls Derived:foo
}
Run Code Online (Sandbox Code Playgroud)
现在将选择非const版本,因为Base::foo它隐藏在Derived类中.
由于Derived::foo隐藏了Base::foo,所以你不能使用实例来调用后者Derived.
现在,让我们取消隐藏Base::foo并进行更多实验.
class Derived : public Base {
public:
using Base::foo; //<----------------this unhides Base::foo
virtual void foo() {
cout << "Derived::foo()" << endl;
}
};
Run Code Online (Sandbox Code Playgroud)
现在在Derived中,两个函数(const和非const版本)都可用,取消隐藏.现在几个有趣的问题.
从现在开始Derived有两个函数unhidden,下面的每个函数都会调用哪个函数?
void f(Derived& obj) {
obj.foo(); //Which function? Base::foo or Derived::foo?
}
void g(const Derived & obj) {
obj.foo(); //Which function? Base::foo or Derived::foo?
}
Run Code Online (Sandbox Code Playgroud)
第一个将调用Derived::foo哪个是非const版本,第二个将调用Base::foo哪个是const版本.原因很简单,使用const对象,只能 调用const函数,但是对于非const对象,都可以调用它们,但是如果可用,则选择非const版本.
请参阅在线演示:http://www.ideone.com/955aY
| 归档时间: |
|
| 查看次数: |
3848 次 |
| 最近记录: |