c++:不要重新定义继承而来的non-virtual函数
2015-05-30 16:40
337 查看
资料摘自<Effective C++>
class B{
public:
void mf();
};
void B::mf(){
std::cout<<"B->mf()"<<std::endl;
}
class D:public B{
public:
void mf();
};
void D::mf(){
std::cout<<"D->mf()"<<std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
D x;
B * pB = &x;
pB->mf();
D * pD = &x;
pD->mf();
}
输出结果:
![](http://img.blog.csdn.net/20150530163840906?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWZlaTE5ODQwOQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
由结果看到,两者都通过对象x调用成员函数mf,但结果却不一致.
造成此一两面行为的原因是,non-virtual函数如B::mf和D::mf都是静态绑定.这意思是,由于pB被声明为一个pointer-to-B,通过pB调用的non-virtual函数永远是B所定义的版本,即使pB指向一个类型为"B派生之class"的对象,如本例所示.
另一方面,virtual函数却是动态绑定,所以它们不受这个问题所束.如果mf是个virtual函数,不论是通过pB或pD调用mf,都会导致调用D::mf,因为pB和pD真正指的都是一个类型为D的对象.
重新编写B
class B{
public:
virtual void mf(); //动态绑定
};
输出结果:
![](http://img.blog.csdn.net/20150530163912979?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWZlaTE5ODQwOQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
现在两者都正确地绑定到指定方法.
注意:任何情况下都不该重新定义一个继承而来的non-virtual函数.
class B{
public:
void mf();
};
void B::mf(){
std::cout<<"B->mf()"<<std::endl;
}
class D:public B{
public:
void mf();
};
void D::mf(){
std::cout<<"D->mf()"<<std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
D x;
B * pB = &x;
pB->mf();
D * pD = &x;
pD->mf();
}
输出结果:
由结果看到,两者都通过对象x调用成员函数mf,但结果却不一致.
造成此一两面行为的原因是,non-virtual函数如B::mf和D::mf都是静态绑定.这意思是,由于pB被声明为一个pointer-to-B,通过pB调用的non-virtual函数永远是B所定义的版本,即使pB指向一个类型为"B派生之class"的对象,如本例所示.
另一方面,virtual函数却是动态绑定,所以它们不受这个问题所束.如果mf是个virtual函数,不论是通过pB或pD调用mf,都会导致调用D::mf,因为pB和pD真正指的都是一个类型为D的对象.
重新编写B
class B{
public:
virtual void mf(); //动态绑定
};
输出结果:
现在两者都正确地绑定到指定方法.
注意:任何情况下都不该重新定义一个继承而来的non-virtual函数.
相关文章推荐
- 如何在Visual Studio和CodeBlocks中反编译C++代码
- C语言快速排序
- C++ 小知识点之引用:“&”
- 【Triangle 】cpp
- 关于C++类的基础
- LeetCode 199. Binary Tree Right Side View
- C语言结构体变量内存分配与地址对齐
- LeetCode 198. House Robber
- C语言小知识点
- 【Container With Most Water】cpp
- c语言字符串 数字转换函数大全
- C语言实现栈的基本操作
- C++模板求n!与1+2+...n
- 【Longest Substring Without Repeating Characters】cpp
- C语言实现无头链表的基本操作
- c++ 基本使用
- C++ ODBC 函数报无法解析的外部函数错误的解决方法
- 【转载】C++的文件和流
- Effective C++ 条款33
- C++ 学习笔记(一):类的声明与编写