重载虚函数并通过指向基的指针调用派生函数 class
overloading virtual function and calling derived function by pointer to base class
#include <bits/stdc++.h>
using namespace std;
class Base {
public:
virtual int function() const {
cout << "Base::function()\n";
return 1;
}
virtual void function(string) const {}
};
class Derived : public Base {
public:
// overloading function() of base
int function(int) const {
cout << "Derived::function()\n";
return 4;
}
};
int main()
{
string s("Whosebug");
Derived d;
Base* b = &d;
//calling derived::function() and function(s)
b->function();
b->function(s);
}
由于重载,名称隐藏出现在派生class。
由于关键字 virtual 在运行时应调用 Derived::function()。
但是代码编译成功。 link : http://ideone.com/fbVm0P
这种奇怪行为的原因是什么?
编辑 1:
d.function();
d.function(s);
如预期的那样没有编译。
导出的class中没有int function() const
。
使用 override
关键字来避免这样的意外,即
class Derived
: public Base
{
public:
// not overriding function() of base
auto function(int) const
-> int override // This won't compile, because it doesn't override.
{
cout << "Derived::function()\n";
return 4;
}
};
重载解析使用静态类型(不是说它会
这里的区别)。所以 b->function()
和 b->function( s )
解析为 Base::function
,没有错误。最后,由于这些
函数已声明 virtual
,最终解决方案将采用
考虑派生 class 中的任何重载。但是没有,所以
将调用基 class 中的函数。
名称隐藏发生在名称查找期间,即重载之前
分辨率,也只关注静态类型;在一个表达式中
像 b->function()
或 b->function( s )
,编译器会忽略
Derived
完全;它对静态类型进行名称查找。姓名
隐藏只会考虑是静态类型
Derived
;一旦编译器在 Derived
中找到 function
,它就会
别再看了。
全局规则相当简单:名称查找(使用静态类型),
然后重载解析(使用静态类型),最后,如果
resolved name是一个虚函数,实际动态确定
功能取决于动态类型。
#include <bits/stdc++.h>
using namespace std;
class Base {
public:
virtual int function() const {
cout << "Base::function()\n";
return 1;
}
virtual void function(string) const {}
};
class Derived : public Base {
public:
// overloading function() of base
int function(int) const {
cout << "Derived::function()\n";
return 4;
}
};
int main()
{
string s("Whosebug");
Derived d;
Base* b = &d;
//calling derived::function() and function(s)
b->function();
b->function(s);
}
由于重载,名称隐藏出现在派生class。
由于关键字 virtual 在运行时应调用 Derived::function()。
但是代码编译成功。 link : http://ideone.com/fbVm0P
这种奇怪行为的原因是什么?
编辑 1:
d.function();
d.function(s);
如预期的那样没有编译。
导出的class中没有int function() const
。
使用 override
关键字来避免这样的意外,即
class Derived
: public Base
{
public:
// not overriding function() of base
auto function(int) const
-> int override // This won't compile, because it doesn't override.
{
cout << "Derived::function()\n";
return 4;
}
};
重载解析使用静态类型(不是说它会
这里的区别)。所以 b->function()
和 b->function( s )
解析为 Base::function
,没有错误。最后,由于这些
函数已声明 virtual
,最终解决方案将采用
考虑派生 class 中的任何重载。但是没有,所以
将调用基 class 中的函数。
名称隐藏发生在名称查找期间,即重载之前
分辨率,也只关注静态类型;在一个表达式中
像 b->function()
或 b->function( s )
,编译器会忽略
Derived
完全;它对静态类型进行名称查找。姓名
隐藏只会考虑是静态类型
Derived
;一旦编译器在 Derived
中找到 function
,它就会
别再看了。
全局规则相当简单:名称查找(使用静态类型), 然后重载解析(使用静态类型),最后,如果 resolved name是一个虚函数,实际动态确定 功能取决于动态类型。