条款4:确定对象在使用前已被初始化

考虑如下设计:

 1 #include<iostream>
 2
 3 using namespace std;
 4
 5 class Entry
 6 {
 7 public:
 8     Entry(const string& name, const string& address, const string& phone);
 9
10 private:
11     string name;
12     string address;
13     string phone;
14     int nums;
15 };
16 Entry::Entry(const string& name, const string& address, const string& phone)
17 {
18     this->name = name;            // 构造函数内的这些语句都是赋值而不是初始化
19     this->address = address;
20     this->phone = phone;
21     this->nums = 0;
22 }
23
24 int main()
25 {
26     Entry entry("name: benxintuzi", "address: 123", "phones: 123456");
27
28     return 0;
29 }

如上所述,在构造函数体内都为赋值语句,而不是初始化语句。C++规定,对象的成员变量的初始化时机发生在进入构造函数之前,这点非常重要。而对于基本变量类型如nums却不能保证进入构造函数之前将其初始化。上述语句的执行是:首先调用name/address/phone的default构造函数,然后在Entry的构造函数中对其进行赋值,如此一来,调用变量的默认构造函数就变得没有什么意义了,反正最终获得的值都会马上被换掉了。为了避免重复性的工作,利用变量的构造函数总会被调用的原则,将上述Entry的构造函数改进如下:

Entry::Entry(const string& name, const string& address, const string& phone) :

name(name), address(address), phone(phone), nums(0)

{ }

利用构造函数的初始化列表,虽然结果是相同的,但是效率会提高很多:因为初始化列表只会调用name等变量的copy构造函数,而不会再次调用Entry的赋值操作符函数了,这样Entry的构造函数体就可以做一些更有意义的事了。同样不指定实参的初始化列表同样有用,比如设计一个Entry的无参构造函数如下:

Entry::Entry() :

name(), address(), phone(), nums(0)

{ }

注意:

对于基本内置类型而言,在构造函数体内赋值与调用初始化列表指定初值,其代价是等同的。但是如果成员变量是const或者references,那么就没办法使用赋值操作了,必须使用初始化列表才能通过编译。所以我们要遵循的规则就是:总是使用初始化列表,这样做最差情况下是等效的,而一般情况下是高效的,甚至有时还是必须的。

C++类的成员初始化次序问题:

  • 先基类后派生类。
  • 类中成员变量的初始化次序依赖与声明次序,与初始化列表排列次序无关。
  • 对于不同编译单元中(一个编译单元就是指能够产生单一目标文件的那些源码:包括源码文件、头文件展开、宏展开等构成的一个大文件)的变量引用问题,为了防止引用了一个还没有被初始化的变量(比如说某些资源句柄之类的),最好的办法就是将被引用的变量通过单例模式创建出来,这样就可以保证正确的初始化顺序了
时间: 2024-11-07 11:41:49

条款4:确定对象在使用前已被初始化的相关文章

Effective C++ 条款四 确定对象被使用前已被初始化

1.对于某些array不保证其内容被初始化,而vector(来自STL)却有此保证. 2.永远在使用对象前初始化.对于无任何成员的内置类型,必须手工完成.      int x = 0;      const int * p = &x; 3.不要混淆赋值与初始化的区别.一般初始化在定义的时候一起进行.而赋值是在定义之后的动作.      比如说在某一个类中的构造函数中,函数的行为都是赋值操作,而非初始化操作.      一般来说,对象的成员变量的初始化动作发生在进入构造函数本体之前.所以,我们一

[effictive c++] 条款04 确定对象被使用前已被初始化

成员初始化 在c和c++ 中,使用为初始化的类型常常会引发不可预料的错误,从而使得我们要花费巨大的时间用于调试查找问题,所以确定对象被使用前已被初始化是个很好的习惯. 永远在使用之前对对象进行初始化.对于无任何成员的内置类型,你必须手工完成初始化操作.因为c++不保证初始化他们. 内置类型意外的其他东西,初始化责任落在构造函数身上.但要注意区分构造函数中的变量是赋值还是初始化.举个例子 class PhoneNumber{...}; class ABEntry{ public: ABEntry(

Effective C++ 条款4 确定对象被使用前已被初始化

1. 对于内置类型,如果变量在全局作用域内定义,默认初始化为0,如果变量在局部作用域内定义,默认不进行初始化; 对于类类型,默认调用默认构造函数进行初始化,如果没有默认构造函数,则必须显式初始化. 2. 构造函数对成员进行初始化的动作发生在初始化列表中而不是函数体内,在函数体内进行的"初始化"实际上是赋值,对于类类型,降低了程序效率,对于内置类型在初始化列表还是在函数体内初始化对于效率没有影响,但在某些特殊情况(例如const变量和引用)必须在初始化列表进行初始化. 3. 类类型的构造

条款4:确定对象被使用前已被初始化

一. 永远在使用对象之前将它初始化 1.对于内置类型,手动完成初始化. 例如:int =0; 2.除了内置类型之外的类型,由构造函数进行初始化:确保每个构造函数都将对象的每一个成员进行了初始化. 二. 特别区分"赋值"和"初始化" 例如:有一个类:A中有一个成员变量string  name; 有一个构造函数:A(const string &n){name=n;}//这是赋值操作而非初始化,这里调用了默认构造函数和赋值运算符 A(const string &a

条款4:确定对象被使用前已被初始化(Make sure that objects are initialized before they&#39;re used)

其实 无论学何种语言 ,还是觉得要养成先声明后使用,先初始化再使用. 1.永远在使用对象之前先将其初始化. 内置类型: 必须手工完成. 内置类型以外的:使用构造函数完成.确保每一个构造函数都将对象的一个成员初始化. shit!!读到这,以前一直以为有些概念独自觉悟到的,大牛们也有这样的想法!!!! 2.区分开assignment & initialization(这个需要再看看,似乎以前的认知是错误的!!!!) initializatin:在default构造函数时才是对非内置类型做初始化. a

条款04 确定对象被使用前已先被初始化

一.概述 手工初始化内置类型对象 构造函数的成员初始化列表 static对象的初始化:包括non-local static和local static 二.细节 1. 你的构造函数使用了成员初始值列表了咩 不使用初始值列表: class A { public: A(const string &s, int i) { //下面都是赋值,而非初始化 s = name; score = i; } private: string name; int score; }; 使用初始值列表: class A {

条款04:确定对象被使用前已被初始化

记住:永远在使用对象前先将它初始化. 1.不要混淆赋值assignment和初始化initialization. ABEntry::ABEntry(const std::string& name,const std::string& address,const std::list<PhoneNumber>& phones)//版本1 { theName = name;//这些都是赋值而非初始化 theAddress = address; thePhones = phon

NO.4: 确定对象被使用前已被初始化

1.为内置对象进行 "手工初始化",因为C++不保证初始化他们(内置类型在赋值与初始化销毁基本相同,最好还是进行初始化列表),在内置类型过多情况下,可选择private函数统一初始化(赋值与初始化效率持平) 2.构造函数最好使用成员初始化列表方式,构造函数体内属于赋值操作,且初始化列表最好与声明变量次序保持一致(成员变量实际初始化次序与声明次序一致) 3.为免除 "跨编译单元之初始化次序"问题,请以 "local-static" 对象替换 &qu

Effective C++ 之 Item 4:确定对象被使用前已先被初始化

Effective C++ Effective C++ Effective C++ Chapter 1. 让自己习惯C++ (Accustoming Yourself to C++) Chapter 1. 让自己习惯C++ (Accustoming Yourself to C++) Chapter 1. 让自己习惯C++ (Accustoming Yourself to C++) Item 4. 确定对象被使用前已先被初始化 (Make sure that objects are initial