好儿郎~志在四方
时光就这样流逝,怎能不心痛。
标签: C++构造函数中调用虚函数
本文章已收录于:

C++交流群: 302558294(欢迎你的加入)
原文地址:http://blog.youkuaiyun.com/alex_my/article/details/44017509 ,感谢原作者总结分享
谈谈关于构造函数中调用虚函数的情况,仅讨论单继承,不考虑虚拟继承和多重继承。
测试平台:VS2013 + Win7X64
一个例子:
#include <stdlib.h>
#include <stdio.h>
class Base
{
private:
int __data;
public:
Base()
{
this->Func();
}
public:
virtual void Func()
{
printf("Base::Func");
}
};
class Deri : public Base
{
public:
Deri()
{
#include <stdio.h>
class Base
{
private:
int __data;
public:
Base()
{
this->Func();
}
public:
virtual void Func()
{
printf("Base::Func");
}
};
class Deri : public Base
{
public:
Deri()
{
this->Func();
}
public:
virtual void Func()
{
printf("Deri::Func\n");
}
};
int main(int argc, char** argv)
{
Deri d;
getchar();
return 0;
}
}
public:
virtual void Func()
{
printf("Deri::Func\n");
}
};
int main(int argc, char** argv)
{
Deri d;
getchar();
return 0;
}
输出:
Base::Func
Deri::Func
首先讨论下对象d的构造情况。
1 先构造基类部分,调用基类Base的构造函数,这个时候,派生类部分还没有产生,这时候虚表应该是绑定基类的,自然调用的是Base::Func()
2 再构造派生类部分,这个时候,虚表发生变化,绑定在派生类上,调用Deri::Func()
虽然,在派生类中有重载Func这个函数,但是,在构造基类部分的时候,派生类的成员数据还没有初始化,如果是调用派生类中的Func,会造成错误,内存越界甚至崩溃。
在函数中,可以通过打印虚表地址:
-- Base::Func()
int* vtl = (int*)*((int*)this);
std::cout << "Base: " << this << " VTable: " << vtl << std::endl;
-- Deri::Func()
int* vtl = (int*)*((int*)this);
std::cout << "Deri: " << this << " VTable: " << vtl << std::endl;
输出:
Base: 0028F980 VTable: 003FDC78
Deri: 0028F980 VTable: 003FDC98
Deri: 0028F980 VTable: 003FDC98
发现,虚表的地址是不断变化的。
-
顶
- 0
-
踩
- 0
我的同类文章
http://blog.youkuaiyun.com
- •C++:什么情况下需要将析构函数定义为虚函数?2016-10-17
- •C、C++中使用const提高程序的健壮性和效率2016-08-30
- •Visual Studio中出现This function or variable may be unsafe错误提示2016-07-27
- •Thinking in C++: 第1章 为什么C++会成功2016-07-16
- •Thinking in C++: 第1章 继承:类型关系2016-07-15
- •C++编程经验分享2016-08-30
- •C++中四种类型转换运算符的使用方法(reinterpret_cast,const_cast,static_cast,dynamic_cast)2016-08-25
- •C++: 友元函数和友元类详解2016-07-17
- •Thinking in C++: 第1章 多态性2016-07-15
- •Thinking in C++: 第1章 对象=特性+行为2016-07-15
参考知识库
核心技术类目
全部主题
Hadoop
AWS
移动游戏
Java
Android
iOS
Swift
智能硬件
Docker
OpenStack
VPN
Spark
ERP
IE10
Eclipse
CRM
JavaScript
数据库
Ubuntu
NFC
WAP
jQuery
BI
HTML5
Spring
Apache
.NET
API
HTML
SDK
IIS
Fedora
XML
LBS
Unity
Splashtop
UML
components
Windows Mobile
Rails
QEMU
KDE
Cassandra
CloudStack
FTC
coremail
OPhone
CouchBase
云计算
iOS6
Rackspace
Web App
SpringSide
Maemo
Compuware
大数据
aptech
Perl
Tornado
Ruby
Hibernate
ThinkPHP
HBase
Pure
Solr
Angular
Cloud Foundry
Redis
Scala
Django
Bootstrap
- 我的简介:
姓名:何树培
专注:C++、Qt程序开发
专业:计算机科学与技术
母校:四川理工学院
联系我:
我的QQ:913970877
C++交流群: 302558294
- 个人资料
-
- 访问:149784次
- 积分:4076
- 等级:
- 排名:第5645名
- 原创:211篇
- 转载:44篇
- 译文:2篇
- 评论:155条
- 博客专栏
Linux环境下C程序开发 文章:24篇
阅读:20601三级数据库等级考试 文章:9篇
阅读:4700蓝桥杯 文章:21篇
阅读:11503
- 阅读排行
- MFC、VC++综合作业题(4600)
- 小何讲进程: Linux进程控制编程 (fork、vfork)(4402)
- C++标准库和标准模板库(4175)
- 《Windows程序设计》复习题(3729)
- 小何讲Linux: 基本文件操作和实例(3621)
- 在Qt中使用C++代码创建界面(3055)
- 软件测试技术之: 白盒测试和黑盒测试(2954)
- 小何讲进程: 编写Linux守护进程方法详解(2737)
- 用C语言讲一讲位运算 入门级(详细图解)(2544)
- Qt: 创建具有复选框的树形控件(2267)
- 文章分类
- 文章存档
- 文章搜索
- 评论排行
- 最新评论
- 手把手教你:用Qt做一个漂亮的电子时钟(纯代码)
好儿郎-志在四方:@miao19920101:不妨贴出你的代码看一看吧。
- 手把手教你:用Qt做一个漂亮的电子时钟(纯代码)
好儿郎-志在四方:@miao19920101:没有原程序,定位不了你的程序出错误的原因。
- 手把手教你:用Qt做一个漂亮的电子时钟(纯代码)
miao19920101:我qDebug除了但到时 hh:mm:ss 但是显示的只有mm:ss为什么呢
- 如何在优快云博客中插入动态图(GIF)
HongdengLi:正好需要,谢谢了
- Qt: 多线程,继承QThread,重写run(理论+实例)
好儿郎-志在四方:@z609932088:天天向上。
- Qt: 多线程,继承QThread,重写run(理论+实例)
DreamLife-i:好好学习
- Qt多线程:QtConcurrent配合lambda表达式(实例)
DreamLife-i:搜藏,日后学习
- 第二章:10道C/C++经典面试题
adj2010:单链表反转感觉有点问题,应该这样tmp = cur;cur = cur.next;tmp.next ...
- 我的求职简历(大三学生)
独立风华:别写“擅长Office、WPS等办公软件的使用”,没啥意义
- Qt creator 编译错误:无法解析的外部符号(命令)
好儿郎-志在四方:亲测可用。
暂无评论