深入理解c++中virtual关键字
- 更新时间:2022-09-23 09:39:24
- 编辑:池紫云
参考资料
- c++项目开发实战入门 PDF 电子书 / 309 MB / 明日科技 推荐度:
- 嵌入式C/C++系统工程师实训教程 PDF 电子书 / 41.7 MB / 庄严 王骁 推荐度:
- 小学生C++趣味编程 PDF 电子书 / 57 MB / 潘洪波 推荐度:
正文内容
virtual
1.virtual关键字主要是什么作用?
c++中的函数调用默认不适用动态绑定。要触发动态绑定,必须满足两个条件:第一,指定为虚函数;第二,通过基类类型的引用或指针调用。
由此可见,virtual主要主要是实现动态绑定。
2.那些情况下可以使用virtual关键字?
virtual可用来定义类函数和应用到虚继承。
友元函数 构造函数 static静态函数 不能用virtual关键字修饰;
普通成员函数 和析构函数 可以用virtual关键字修饰;
3.virtual函数的效果
class GrandFather { public: GrandFather() {} virtual void fun() { cout << "GrandFather call function!" << endl; } };
class Father : public GrandFather { public: Father() {} void fun() { cout << "Father call function!" << endl; } };
class Son : public Father { public: Son() {} void fun() { cout << "Son call function!" << endl; } };
void print(GrandFather* father) { father->fun(); }
int _tmain(int argc, _TCHAR* argv[]) { Father * pfather = new Son; pfather->fun(); GrandFather * pgfather = new Father; print(pgfather); return 0; }
4.virtual的继承性 只要基函数定义了virtual,继承类的该函数也就具有virtual属性 即 GrandFather Father Son同时定义virtual void fun()与GrandFather一个定义virtual void fun效果是一样的
5.虚析构函数
class GrandFather { public: GrandFather() {} virtual void fun() { cout << "GrandFather call function!" << endl; }
~GrandFather() { cout << "GrandFather destruction!" << endl; } };
class Father : public GrandFather { public: Father() {} void fun() { cout << "Father call function!" << endl; }
~Father() { cout << "Father destruction!" << endl; } };
class Son : public Father { public: Son() {} void fun() { cout << "Son call function!" << endl; }
~Son() { cout << "Son destruction!" << endl; } };
void print(GrandFather* p) { p->fun(); }
int _tmain(int argc, _TCHAR* argv[]) { Father * pfather = new Son; delete pfather; return 0; }
6. 纯虚函数 纯虚函数定义如下:
class GrandFather { public: GrandFather() {} virtual void fun() = 0 { cout << "GrandFather call function!" << endl; }
virtual ~GrandFather() { cout << "GrandFather destruction!" << endl; } };
7.虚继承 虚继承主要解决交叉继承带来的问题。这里给出一片参考文章c++虚继承。 给一个例子如下
class GrandFather { public: GrandFather() {} void fun() { cout << "GrandFather call function!" << endl; }
virtual ~GrandFather() { cout << "GrandFather destruction!" << endl; } };
class Father1 : public GrandFather { public: Father1() {} void fun() { cout << "Father call function!" << endl; } };
class Father2 : public GrandFather { public: Father2() {} void fun() { cout << "Father call function!" << endl; }
};
class Son : public Father1, public Father2 { public: Son() {} //void fun() //{ // cout << "Son call function!" << endl; //} };
void print(GrandFather* p) { p->fun(); }
int _tmain(int argc, _TCHAR* argv[]) { Son* son = new Son; son->fun(); return 0; }
8. 构造函数和析构函数中的虚函数 如果在构造函数或析构函数中调用虚函数,则运行的是为构造函数或析构函数自身类型定义的版本
9.虚函数的实现机制 关于虚函数的实现机制,我们以后在介绍。
10.小结 关于virtual关键字的用法总结如上,有错误或者总结不到位的情况请能帮本人指出!
11.例子
class classA { public: classA() { clear(); } virtual ~classA() { } void clear() { memset(this , 0 , sizeof(*this)); } virtual void func() { printf("func\n"); } };
class classB : public classA { };
int main(void) { classA oa; classB ob; classA * pa0 = &oa; classA * pa1 = &ob; classB * pb = &ob; oa.func(); // 1 ob.func(); // 2 pa0->func(); // 3 pa1->func(); // 4 pb->func(); // 5 return 0; }
谈谈我的理解,当 classA oa; oa.func(); 不存在动态调用的过程,所以func虽然是虚函数,但是函数调用不通过虚表访问,所以即使
memset(this , 0 , sizeof(*this));
在执行classB ob;的时候,注意memset的是classA的地址,所有ob的虚表是存在的
即是如下,通过指针或引用(动态绑定)访问oa的func函数(需要从虚表访问),会出错
访问ob的func和函数,无论静态访问还是动态访问,都不会出错
当把classB的代码改成如下时
class classB : public classA
<PRE style="FONT-WEIGHT: bold" class=cpp name="code">{</PRE><PRE style="FONT-WEIGHT: bold" class=cpp name="code"> classB() { clear(); } virtual ~classB() { } void clear() { memset(this , 0 , sizeof(*this)); }</PRE><BR> <PRE></PRE> <PRE style="FONT-WEIGHT: bold" class=cpp name="code">};</PRE>输出为
c++相关教程
-
C++保存txt文件实现方法代码实例
这篇文章主要介绍了C++保存txt文件实现方法代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
发布时间:2022-04-08
-
C++子类父类成员函数的覆盖和隐藏实例详解
给大家整理一篇关于C++的教程,这篇文章主要介绍了C++子类父类成员函数的覆盖和隐藏实例详解的相关资料,需要的朋友可以参考下
发布时间:2022-09-12
-
C语言实现C++继承和多态的实例内容
本文主要给大家简单讲诉了C和C++的区别以及如何使用C语言模拟实现C++继承和多态,并附上示例代码,是篇相当不错的文章,推荐给喜欢C语言的小伙伴们
发布时间:2021-06-10
-
c++11&14-多线程要点汇总
这篇文章主要介绍了c++11&14-多线程的使用方法,文中代码非常详细,方便大家更好的参考和学习,感兴趣的朋友快来了解下
发布时间:2022-04-08
-
C/C++函数调用栈的实现方法
给网友朋友们带来一篇关于C++的教程,这篇文章主要介绍了C/C++函数调用栈的实现方法,可实现一个简单的脚本解释器,具有一定的参考借鉴价值,需要的朋友可以参考下
发布时间:2022-06-22
-
如何理解C++ 临时变量的常量性
这篇文章主要介绍了如何理解C++ 临时变量的常量性,帮助大家更好的理解和学习c++ 变量,感兴趣的朋友可以了解下
发布时间:2022-04-02
-
VC++中进程与多进程管理的方法详解
这篇文章主要介绍了VC++中进程与多进程管理的方法,以实例形式详细分析了进程与多进程管理中所涉及的进程、子进程、进程的互斥运行与进程的结束等概念与具体实现方法,非常具有参考借鉴价值,需要的朋友可以参考下
发布时间:2021-05-28