GeekBand C++面向对象高级编程(下) 第一周学习笔记

96
淡定若然
2017.02.11 12:21* 字数 1757

本周学习内容回顾

转换函数

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对象的size32字节Apple对象的size40字节

编译器将空类size1字节只含有非虚函数的类size1字节

含有虚函数不含数据的类大小为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对象size40字节,基类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对象的size32字节Apple对象的size40字节

编译器将空类size1字节只含有非虚函数的类size1字节

含有虚函数不含数据的类大小为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对象size40字节,基类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下衍生类的对象模型会占据一部分基类本身的填充空间?

表示不是很明白...

学习笔记
Web note ad 1