本周学习内容回顾
转换函数
conversion function
non-explicit-one-argument ctor
两者都用于实现对象类型转换
当conversion function和non-explicit-one-argument ctor同时存在时会引发ambiguous调用错误
而显示的explicit-one-argument cotr与conversion function共存时需要显式调用构造函数之后才可以得到期望的结果
pointer-like class
智能指针
智能指针是一个模板类,内含一根真正的指针
智能指针重载operator*()和operator->()
对于*运算符运算会消耗掉*
对于->运算符运算会将结果继续加上->
迭代器
list<Foo>::iterator ite;
*ite获得一个 Foo object
ite->method;意思是调用Foo::method()
相当于(*ite).method();
相当于(&(*ite))->method();
function-like class
functor
标准库中仿函数使用一个奇特的base_class
namespace
不同命名空间互相独立
用于解决不同部门或者不同个人之间防止出现函数重名或者全局变量重名所造成的二义性问题
class template,类模板
function template 函数模板
member template 成员模板
specialization 模板特化
partial specialization 模板偏特化
个数的偏特化
范围的偏特化
template template parameter 模板模板参数
关于C++标准库
由仿函数functors形成算法库algorithm
容器container通过迭代器iterator调用algorithm中的方法实现各种运算
C++11的三个新特性介绍
varadic templates
数量不定的模板参数
关键字...就是一个所谓的pack(包)
在varadic tempaltes中 sizeof...(args)获得参数的个数
auto
两种不可应用auto关键字的情况:
1.coder本身对变量类型并不明确
2.直接用auto声明一个变量但是并没有赋值或者初始化的过程
ranged-base for loop
语法:for(decl: coll) {statement;}
通过值传递
for(auto elem: vec) { ...;}
按引用传递
for(auto& elem: vec) {...;}
关于reference的理解
object和其reference大小相同,地址相同(当然这是假象),另java语言中所有的变量都是reference
基于这个假象,所以reference与object相比在被调用端的写法和调用端的接口均相同
因此reference通常不用于声明变量,而是用于参数类型和返回值类型的描述
函数签名包括 函数名、参数表、以及()后面有可能存在的const关键字
复合&继承关系下的构造和析构
构造:
先调用基类的默认构造函数
然后调用component的默认构造函数
最后执行自身的构造
析构:
先析构自身
然后析构component
最后析构基类
关于作业的思考
VS2008编译器x64环境下的对象模型
Fruit对象的size为32字节Apple对象的size为40字节
编译器将空类size为1字节只含有非虚函数的类size为1字节
含有虚函数不含数据的类大小为8字节
vptrsize为8字节
对象初始地址为71FCE8
int no首地址为71FCF0
相对对象初始地址偏移量为8字节
vptr的size为8字节,占位8字节
double weight首地址为71FCF8
相对no首地址偏移量为8字节
相对对象初始地址偏移量为16字节
int型变量size为4字节,但是计算得占位8字节,故而填充量为4字节
char key首地址为71FD00
相对weight首地址偏移量为8字节
相对对象初始地址偏移量为24字节
对象总size为32字节
double型变量size为8字节,占位8字节
char型变量size为1字节
key首地址到Fruit结束之间的内存空间为8字节,故而填充量为7字节
Apple对象size为40字节,基类Fruit对象为32字节
由基类继承而来的数据等同基类对象模型
Apple类自身首地址为71FD28
int size首地址为71FD48
intsize相对Apple对象首地址偏移量为32字节,等于基类Fruit所占内存空间大小
char types首地址为71FD4C
相对size首地址偏移量为4字节,等于intsize所占的内存空间大小
chartypes首地址相对Apple对象首地址偏移量为36字节,Apple大小为40字节,计算得types占位4字节,故而填充量为3字节
VS2008编译器Win32环境下的对象模型
Fruit对象的size为32字节Apple对象的size为40字节
编译器将空类size为1字节只含有非虚函数的类size为1字节
含有虚函数不含数据的类大小为4字节
vptrsize为4字节
对象初始地址为8FFC38
int no首地址为8FFC40
相对对象初始地址偏移量为8字节
vptr的size为4字节,占位8字节,故而填充量为4字节
double weight首地址为8FFC48
相对no首地址偏移量为8字节
相对对象初始地址偏移量为16字节
int型变量size为4字节,但是计算得占位8字节,故而填充量为4字节
char key首地址为8FFC50
相对weight首地址偏移量为8字节
相对对象初始地址偏移量为24字节
对象总size为32字节
double型变量size为8字节,占位8字节
char型变量size为1字节
key首地址到Fruit结束之间的内存空间为8字节,故而填充量为7字节
Apple对象size为40字节,基类Fruit对象为32字节
由基类继承而来的数据等同基类对象模型
Apple类自身首地址为8FFC08
int size首地址为8FFC28
intsize相对Apple对象首地址偏移量为32字节,等于基类Fruit所占内存空间大小
char types首地址为8FFC2C
相对size首地址偏移量为4字节,等于intsize所占的内存空间大小
chartypes首地址相对Apple对象首地址偏移量为36字节,Apple大小为40字节,计算得types占位4字节,故而填充量为3字节
相同代码在GCC编译器win32环境下执行的结果如下
对于Fruit的对象模型
vptr大小为4字节
vptr到int no之间没有填充
最后的char key 占1字节后被填充至8字节
对于Apple的对象模型
基类的char key本身占据1字节然后填充至8字节
但是衍生类的int size从char key偏移量4字节位置即开始填充
衍生类的char types占据1字节然后又重新填充至8字节
可能的原因是在GCC下衍生类的对象模型会占据一部分基类本身的填充空间?
表示不是很明白...