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 ...
随机推荐
- 面试后 follow up letter 分享
分享一下最近面试外企的follow up letter. Dear Mr. Xu, Thank you again for the time you and Mr. Guo spent wit ...
- excel poi 文件导出,支持多sheet、多列自动合并。
参考博客: http://www.oschina.net/code/snippet_565430_15074 增加了多sheet,多列的自动合并. 修改了部分过时方法和导出逻辑. 优化了标题,导出信息 ...
- 使用PHP预定义变量得到url地址及相关参数
获取url地址栏参数多种方法:$_SERVER["SERVER_PORT"]//获取端口$_SERVER['HTTP_HOST']//获取域名或主机地址 如www.sina.com ...
- dedecms织梦二级菜单的实现方法
首先,复制代码: 程序代码 {dede:channelartlist typeid='top' cacheid='channelsonlist'} {dede:channel type='son' n ...
- shell 脚本中 命令
终端工具tput和stty是两款终端处理工具tput cols,lines,longname,cpu 100 100 输入密码时,不能让输入的内容显示出来.用stty #!/bin/bash #Fil ...
- jQuery 树形结构
强大的jquery.ztree树形菜单插件支持多种树形菜单导航 http://www.17sucai.com/pins/2259.html 演示: http://www.17sucai.com/pin ...
- Flask jQuery ajax
http://www.runoob.com/jquery/jquery-ref-ajax.html http://jun1986.iteye.com/blog/1399242 下面是jQuery官方给 ...
- Typefaces and Personalities (字体与性格)
Boring afternoon, searching something fun. See this article What Your Favorite Font Says About You , ...
- 递归删除.DS_Store文件
删除svn文件 sudo find . -name ".DS_Store" -exec rm -r {} \; sudo find . -name ".git" ...
- 查看Oracle是否锁表
--Oracle数据库操作中,我们有时会用到锁表查询以及解锁和kill进程等操作,那么这些操作是怎么实现的呢?本文我们主要就介绍一下这部分内容. --(1)锁表查询的代码有以下的形式: select ...