zoukankan      html  css  js  c++  java
  • 条款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++类的成员初始化次序问题:

    • 先基类后派生类。
    • 类中成员变量的初始化次序依赖与声明次序,与初始化列表排列次序无关。
    • 对于不同编译单元中(一个编译单元就是指能够产生单一目标文件的那些源码:包括源码文件、头文件展开、宏展开等构成的一个大文件)的变量引用问题,为了防止引用了一个还没有被初始化的变量(比如说某些资源句柄之类的),最好的办法就是将被引用的变量通过单例模式创建出来,这样就可以保证正确的初始化顺序了
  • 相关阅读:
    关于postgresql——常用操作指令
    linux 下查看机器是cpu是几核的
    ASP.NET跨平台实践:无需安装Mono的Jexus“独立版”
    .NET平台开源项目速览(4).NET文档生成工具ADB及使用
    Hadoop学习---安装部署
    c# 模拟表单提交,post form 上传文件、大数据内容
    半小时学会上传本地项目到github
    统计网卡TX(发送)RX(接受)流量脚本
    mysql mysqldump只导出表结构或只导出数据的实现方法
    psutil--跨平台的进程管理
  • 原文地址:https://www.cnblogs.com/benxintuzi/p/4535556.html
Copyright © 2011-2022 走看看