Effective C++阅读记录--前言(1)

Effective C++阅读记录--前言(1)

定义的本质

Object(对象)的定义给编译器提供配置内存的地点说明。

function(函数)或者function template(函数模板)定义式为编译器提供函数本体(function body)

对象数组的初始化

C Array[10];

default constructor: 无需任何引数(argument)被调用,或者引数都有默认值。

想要定义一组包含类C的对象数组,如果按照以上代码会定义包含十个C实例的数组,而且会执行类C的默认构造函数(default constructor)。

但是当类对象没有默认构造函数的话怎么办呢?

既然我们不能直接默认初始化对象,我们可以初始化指向该对象数组的指针(其实就是把构造对象转移到构造指向对象的指针)。

C *ptrArray[10]; //先初始化指针,实际上尚未分配对象
ptrArray[0] = new C(args); //再配置对象

疑问1:如果不使用默认构造函数,如何为每个数组元素调用其他的构造函数?

拷贝构造函数(copy constructor)

本质上就是定义类如何以”by value“的方式传递和传回对象。

函数传参会调用到copy constructor。

只要编译器决定产生中介的暂时性对象,就会需要copy constructor调用动作。

pass by value = 调用copy constructor。

初始化(initialization)与赋值(assignment)

初始化:对象的初始化发生在它初次获取某个值的时候,总是调用constructor实现的。

赋值:发生在以初始化对象被赋予新值的时候。

虽然二者都会让对象有新值,但是调用的函数是不一样的。

string s1; //调用的是默认初始化函数
string s2("hello"); //直接初始化,调用普通构造函数
string s3 = s2; //调用拷贝构造函数
s1 = s3; //由operator=执行

初始化会检验传递的引数(argument)是否是合法的,但是赋值操作不会。

在assignment(赋值)运算符为一个新值配置内存之前,需要先释放原来的值的内存。assignment认定参数是合法的,反而需要检测有没有自己赋给自己的情况,力保配置新内存前释放旧内存。

但是constructor操作需要检验参数的正确性,确保member data(成员数据)都能被适当初始化。

Effecetive C++阅读记录--条款1

尽量以const和inline取代#define

const和inline是编译器处理的工作,预处理器处理#define。因此尽量用编译器取代预处理器。

#define ASPECT_RATIO 1.653

一般define定义宏出现在头文件中,使用的时候头文件可能不是你自己写的,但是ASPECT_RATION由于被预处理器全部处理成了1.653,并没有进入符号表(symbol table)里面。因此当你使用了这个宏又出错的时候,可能会对1.653这个数字很懵,你联想不到是ASPECT_RATIO出了问题。原因:程序内所使用的名称并未出现在符号表之中。

const double ASPECT_RATION = 1.653; 

可以使用以上,定义一个常量。

当这个常量是给某个class专属设计的时候,需要做两样工作。

①为了将这个常量的scope(生存空间)局限在class之内,需要把他作为class的member。

②为了让这个常量只有一份实体,需要让它成为一个static member(也就是static关键字能避免一个变量被重复定义吗)。

posted @ 2020-11-28 13:38  LeeSCUT  阅读(93)  评论(0)    收藏  举报