C++对象模型学习笔记
1. 全局变量是如何初始化的
//global var
A a; int main()
{
cout<<a<<endl;
return ;
}
如上述例子,全局变量a是在main()函数之前便被初始化的,但是它是如何被初始化的呢?答案是所谓的静态初始化!
2. C++对C进行封装的布局成本
C++在布局和存取时间上主要的额外负担是由virtual 机制引起的,包括:
virtual function机制:用于支持有效率的“执行期绑定”
virtual base class:用以实现“多次出现在继承体系中的base class ,有一个单一而被共享的实体”
此外,还有一些多重继承下的额外负担,发生在“一个derived class 和其第二或后继之 base class 的转换”之间。然而,一般而言,并没有什么天生的理由说C++程序一定比C兄弟庞大或迟缓。
3. 父类与子类的指针有什么不同?
看下面例子:
class ZooAnimal
{
public:
ZooAnimal(): name("")
{
cout<<"ZooAnimal::ZooAnimal()"<<endl;
} ZooAnimal(string str): name(str)
{
cout<<"ZooAnimal::ZooAnimal(string)"<<endl;
} virtual ~ZooAnimal()
{
cout<<"ZooAnimal::~ZooAnimal()"<<endl;
} virtual void rotate()
{
cout<<"ZooAnimal::rotate()"<<endl;
} protected:
int loc;
string name;
}; class Bear: public ZooAnimal
{
public:
Bear()
{
cout<<"Bear::Bear()"<<endl;
} Bear(string str): ZooAnimal(str)
{
cout<<"Bear::Bear(string)"<<endl;
} ~Bear()
{
cout<<"Bear::~Bear()"<<endl;
} void rotate()
{
cout<<"Bear::rotate()"<<endl;
} virtual void dance()
{
cout<<"Bear::dance()"<<endl;
} protected:
enum Dances{DAN, SLEEP}; Dances dances_known;
int cell_block;
}; int main()
{
cout<<"sizeof(ZooAnimal):"<<sizeof(ZooAnimal)<<endl;
cout<<"sizeof(Bear):"<<sizeof(Bear)<<endl; Bear b("Yogi");
Bear *pb = &b;
ZooAnimal *pbr = &b; return ;
}
指针pb 和 pbr 有什么不同呢?它们都指向Bear对象b的第一个字节,其间的差别是,pb所涵盖的地址包含了整个Bear 对象,而 pbr 所涵盖的地址只包含Bear 对象中的ZooAnimal 部分!
4. 自定义类什么时候自动生成默认构造函数?
答案:在编译器需要的时候,什么时候需要呢,有如下四种情况:
合成出来的构造函数只执行编译器所需的行动。也就是说,即使有需要为自定义类合成一个默认构造函数,那个构造函数也不会将类的数据成员初始化为0。
因此,类的设计者必须提供一个明显的默认构造函数,将数据成员初始化!
全局对象的内存保证会在程序激活的时候被清零,本地变量对象配置于程序的堆栈中,Heap 对象配置与自由空间中,都不一定被清零。
1. 如果一个类 B 没有任何构造函数,但它内含有一个数据成员A a,而 A 有默认构造函数,那么编译器需要为这个类 B 合成一个默认构造函数。
class Foo
{
public:
Foo() {...}
Foo(int) {...}
}; class Bar
{
public:
Foo f;
char *str;
};
如上例,编译器会自动为类Bar合成一个默认构造函数。被合成的Bar default constructor 内含必要的代码,能够调用 class Foo 的default constructor 来处理数据成员f的初始化,但它并不产生任何代码来初始化Bar::str。被合成的default constructor 看起来可能像这样:
inline Bar::Bar()
{
//C++伪码
f.Foo::Foo();
}
2. 如果该类继承自一个带有默认构造函数的基类,那么编译器也会自动合成一个默认构造函数;
3. 带有一个Virtual Function 的类,这时,编译器也会为之合成一个默认构造函数。
4. 带有一个Virtual Base Class 的类,如下例子所示:
class X
{
public:
int i;
}; class A: public virtual X
{
...
} class B: public virtual X
{
...
} class C: public A, public B
{
...
}
那么,编译器将会为类C合成一个默认构造函数!
注意:C++新手一般有两个常见的误解:
1. 任何class 如果没有定义default constructor,就会被合成一个。
2. 合成的default constructor 会初始化数据成员。
5. 复制构造函数的相关问题
类的复制构造函数的一般模式为:
X::X(const X& x)
{
....
}
5.1 什么情形会调用复制构造函数
有三种情况,分别如下:
1) 赋值操作,例如:
class X { ...};
X a;
X b = a; //copy constructor
2) 对函数传递类参数时,例如:
void foo(X x)
{
...
} X a;
foo(a); //copy constructor
3) 当函数传回一个类对象时,这个时候可能编译器做了优化,因此,可能copy constructor 不被调用。例如:
X foo()
{
X a;
return a;
} X b = foo(); //copy constructor
5.2 当类设计者没有定义类的复制构造函数时如何初始化类数据成员?
其内部是以所谓的默认逐个成员初始化的方法完成的。也就是把每一个内建的或派生的数据成员的值从某个对象拷贝一份到另一个对象身上。
5.3 默认构造函数和复制构造函数在必要的时候才由编译器产生出来。
C++对象模型学习笔记的更多相关文章
- Delphi 对象模型学习笔记(转)
摘要 Borland Object Pascal 对象模型(现在已经正是命名为 Delphi 语言)与其他 OOP 语言一样,都提供了一些基础服务: 如对象创建服务.对象释放服务.对象识别服务 ...
- VSTO学习笔记(二)Excel对象模型
原文:VSTO学习笔记(二)Excel对象模型 上一次主要学习了VSTO的发展历史及其历代版本的新特性,概述了VSTO对开发人员的帮助和效率提升.从这次开始,将从VSTO 4.0开始,逐一探讨VSTO ...
- maven权威指南学习笔记(三)——一个简单的maven项目
目标: 对构建生命周期 (build lifecycle),Maven仓库 (repositories),依赖管理 (dependency management)和项目对象模型 (Project O ...
- jQuery学习笔记(一):入门
jQuery学习笔记(一):入门 一.JQuery是什么 JQuery是什么?始终是萦绕在我心中的一个问题: 借鉴网上同学们的总结,可以从以下几个方面观察. 不使用JQuery时获取DOM文本的操 ...
- ASP.NET MVC Web API 学习笔记---第一个Web API程序
http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html GetListAll /api/Contact GetListBySex ...
- [原创]java WEB学习笔记54:Struts2学习之路---概述,环境的搭建
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- DirectX 总结和DirectX 9.0 学习笔记
转自:http://www.cnblogs.com/graphics/archive/2009/11/25/1583682.html DirectX 总结 DDS DirectXDraw Surfac ...
- VSTO学习笔记(十五)Office 2013 初体验
原文:VSTO学习笔记(十五)Office 2013 初体验 Office 2013 近期发布了首个面向消费者的预览版本,我也于第一时间进行了更新试用.从此开始VSTO系列全面转向Office 201 ...
- VSTO学习笔记(三) 开发Office 2010 64位COM加载项
原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...
随机推荐
- POJ3274-牛的属性-HASH-ACM
原题:POJ3274 参考:进击的阿俊 已知有n头牛,用一个K位二进制数Ak,Ak-1,...,A1表示一头牛具有的特征,Ai=1表示具有特征i.现给定按顺序排列的N头牛的k位特征值,称某个连续范围内 ...
- action 关联
<act_window context="{'product_id': active_id}" id="act_stock_product_location_ope ...
- #module-django.db.models
Models A model is the single, definitive source of information about your data. It contains the esse ...
- DevOps - Development And Operations
简介: 研发运维一体化 相关资料: 关于DevOps你必须知道的11件事 我眼中的DevOps DevOps 门户 docker for dotnet系列 docker4dotnet #1 前世今生 ...
- 2. SharePoint Online 开发,请联系qq512800530。加好备注。(不要发站内信。。。)
///(不要发站内信...) <meta name="keywords" content="SharePoint Online, SP Online, SPO, S ...
- BZOJ 3240 矩阵游戏
Description 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的\(n\)行\(m\)列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质:若用\(F[i][j]\)来 ...
- 对话Facebook人工智能实验室主任、深度学习专家Yann LeCun
对话Facebook人工智能实验室主任.深度学习专家Yann LeCun Yann LeCun(燕乐存),Facebook人工智能实验室主任,NYU数据科学中心创始人,计算机科学.神经科学.电子电气科 ...
- nosql数据库选型
http://blogread.cn/it/article/6654 今天在书店里翻完了一遍<七天七数据库>.这本书简单介绍了postgreSQL,riak,mongodb,HBase,r ...
- 在Hibernate中分别使用JDBC和JTA事务的方法
在Hibernate中使用JDBC事务 Hibernate对JDBC进行了轻量级的封装,它本身在设计时并不具备事务处理功能.Hibernate将底层的JDBCTransaction或JTATransa ...
- div大小如何改变设置
如果改变更改div大小尺寸. 首先我们要知道DIV大小是由高和宽确定,要修改DIV容积大小我们设置css宽度和css高度即可实现改变DIV盒子大小. 一.改变div大小实例 为了实验便于观察DIV盒子 ...