• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 深入理解c++中virtual关键字

深入理解c++中virtual关键字

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c++ virtual,virtual c++ 6.0下载,virtual c++下载,virtual c++ 6.0,c++ virtual函数等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

1.virtual关键字主要是什么作用?
c++中的函数调用默认不适用动态绑定。要触发动态绑定,必须满足两个条件:第一,指定为虚函数;第二,通过基类类型的引用或指针调用。
由此可见,virtual主要主要是实现动态绑定。

2.那些情况下可以使用virtual关键字?
virtual可用来定义类函数和应用到虚继承。

友元函数 构造函数 static静态函数 不能用virtual关键字修饰;
普通成员函数 和析构函数 可以用virtual关键字修饰;

3.virtual函数的效果

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;
}
</div>
输出为 Son call function
       Father call function

4.virtual的继承性
只要基函数定义了virtual,继承类的该函数也就具有virtual属性
即 GrandFather Father Son同时定义virtual void fun()与GrandFather一个定义virtual void fun效果是一样的

5.虚析构函数

 ~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;
}
</div>
以上代码输出:Father destruction!
                             GrandFather destruction!
执行了Son的构造函数,没执行Son的析构函数,故把GrandFather的析构函数设置为virtual
则输出: Son destruction!
        Father Destruction!
        GrandFather destruction!

6. 纯虚函数
纯虚函数定义如下:

 virtual ~GrandFather()
 {
  cout << "GrandFather destruction!" << endl;
 }
};
</div>
纯虚函数为后代类提供可覆盖的接口,但这个类中的版本决不会调用。
含有(或继续)一个或多个纯虚函数的类是抽象基类,抽象基类不能实例化!
继承类只有重写这个接口才能被实例化


7.虚继承
虚继承主要解决交叉继承带来的问题。这里给出一片参考文章c++虚继承。
给一个例子如下

 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;
}
</div>
编译时会提示报错对fun的访问不明确
如果Father1和Father2都用虚继承继承GrandFather类则可以解决这个问题

8. 构造函数和析构函数中的虚函数
如果在构造函数或析构函数中调用虚函数,则运行的是为构造函数或析构函数自身类型定义的版本


9.虚函数的实现机制
关于虚函数的实现机制,我们以后在介绍。

10.小结
关于virtual关键字的用法总结如上,有错误或者总结不到位的情况请能帮本人指出!

11.例子

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;
}
</div>
补充一个例子,这个程序输出依次是
func
func
出错
func
func

谈谈我的理解,当
classA oa;
oa.func();
不存在动态调用的过程,所以func虽然是虚函数,但是函数调用不通过虚表访问,所以即使
代码如下:</div>

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 深入理解c++中virtual关键字
  • C++中virtual继承的深入理解

相关文章

  • 2017-05-28详解C++编程中标记语句与复合语句的写法
  • 2017-05-28C语言之栈和堆(Stack && Heap)的优缺点及其使用区别
  • 2017-05-28C/C++ 中堆和栈及静态数据区详解
  • 2022-04-30学编程难吗?多久能入门?
  • 2017-05-28C++流操作之fstream用法介绍
  • 2017-05-28枚举和宏的区别详细解析
  • 2017-05-28C++中的常量定义小结
  • 2017-05-28C++之类的静态变量
  • 2017-05-28基于结构体与指针的详解
  • 2017-05-28C++编译器无法捕捉到的8种错误实例分析

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 深入解析C++的WNDCLASS结构体及其在Windows中的应用
    • C语言实现Linux下的socket文件传输实例
    • C/C++的浮点数在内存中的存储方式分析及实例
    • C语言编程中从密码文件获取数据的函数总结
    • c++中处理相关数学函数
    • 全局静态存储区、堆区和栈区深入剖析
    • C++实现一维向量旋转算法
    • C语言数据结构 双向链表的建立与基本操作
    • C语言中查找字符在字符串中出现的位置的方法
    • C++ auto类型说明符

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有