Effective C++ 读书笔记(4)

条款四:确定对象在使用前已经初始化

这一条也可以说是在成员定义的时候同时赋予一个初始的数值,有过C编程经验的人对指针定义的初始化应该不陌生,指针

定义的时候同时给予一个初始化的值,一般是为NULL,这样就不会出现野指针的情况,同时在指针空间释放的时候也注意将对应

的指针赋予一个NULL的值,这样就不会出现指针指向一个无效的地址的情况!同样在C++里面,类作为主要的自定义类型,其成员

函数在类对象构造的时候也要做一定的初始化!

附加说一下变量的定义与声明,变量定义是指的编译器会按照变量的类型在内存中申请一定的空间,如果此时你没有对这

块空间做任何的初始化,那么这个变量的值就是这块内存中的数据,这个数据可以是任何无效的数据!相对应的声明主要是告诉编译

器,这个变量或者其他的对象在其他对应已经定义了,这里只是起到一个符号链接的作用,在C++中声明主要包括以下几方面:

1.用extern来声明的变量,包括内置变量或者自定义的变量,例如:extern int number;

2.函数声明,int max(int 1, int b);

3.类的声明;类其实是跟C语言中的struct结构体是相同的,只是默认的成员变量的访问权限不同;

4.模板的声明;template<typename T> class GraphNode;

以上提到的声明在工程中都是要放到对应的.hpp文件中的,其实还有inline函数,模板的定义等也是要放到对应的.hpp

的文件中,总之不涉及到内存空间申请的都是要放到.hpp文件中。

接着将初始化问题,对于内置类型,一般人都没有初始化的习惯,例如对于int类型变量,一般都是定义int tmp;没

有初始化,其实为了统一性和不确定的问题出现,最好也赋予初始值!

对于类的初始化问题,例如:

class People{
private:
    int age_;
    string sex_;
    Address addr_;
public:
     ....
}
People类含有三个数据成员,我们要在People对象构造的时候对这些成员进行初始化,对应的我们可以这样写类的构

造函数:

People(int age, string sex, Address addr):age_(age),sex_(sex),addr_(addr){}

上面在调用People的构造函数之前就首先对类的成员变量进行了初始化,注意与下面这种方式的区别:

People(int age, string sex, Address addr){
	age_ = age;
	sex_ = sex;
	add_ = addr;
}

虽然这种方式在很多情况下不会出错,但是对程序的性能方面对有影响,第一种方式中,只是调用了对应数据成员的构

造函数,而第二种方式中首先调用了成员的构造函数,然后又调用了成员的赋值构造函数,明显在效率上会有很大的差别!虽然

这两种方式对内置类型的成员函数没有区别,但是为了统一还是建议采用第一种方式!

需要注意的是在第一种方案中,也是就成员的初始化列表中,成员的顺序是有要求的,一般是先父类的成员初始化,然

在本身成员的初始化,在同一对象的成员之间,初始化的顺序最好与成员在类中声明的顺序相同!

在本书中还介绍了一种静态成员变量的初始化问题,这里说的静态变量指的是全局的变量,命名空间变量以及局部的

static成员变量,他们之间存在的依赖关系可能造成不确定的错误;例如在上面的定义的People类中,有一个头文件

people.hpp中包含extern People WHZ;这样当在其余的文件中用到了对象WHZ的时候,如果WHZ还没有进行相关的

初始化,那么将会出现不确定的问题,对应的解决办法是将全局的变量转变为局部的静态变量,例如:

//people.hpp
class People{....};,
People& getwhz(){
	static People whz;
	return whz;
}

//student.hpp
class Student{....};
Student::Student(){
    ......
    int age = getwhz().get_age();
    ......
}

这样就保证了在Student对象构建的时候首先能保证People对象是已经初始化的,不会出现引用未初始化成员的情况

这样当你没有调用getwhz的时候也不会对whz这个对象进行构造函数调用,注意局部函数中的static成员是一直存在的,所以

可以返回一个局部static对象的引用。


请记住:

  • 为内置型对象进行手工的初始化,因为C++不保证能初始化他们;
  • 构造函数最好用成员初始化列表,而不要在构造函数的内部采用赋值操作,初值列表中的成员的顺序要与类中成员的顺序相同
  • 为避免"跨编译单元的初始化顺序"问题,建议通过local static对象替换non-local static 对象


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值