使用类成员初始化特性简化构造代码
来源:互联网 发布:淘宝外观专利侵权 知乎 编辑:程序博客网 时间:2024/05/29 03:34
一个新的C++0x特性称为类成员初始化,它允许您在声明数据成员时单一地初始化数据。了解如何使用此功能,以简化您的代码,减少潜在的错误,使你的代码更易读。
一般来说,初始化成员数据的工作是在构造函数里完成的。如果类有多个构造函数并且每个构造函数都分别初始化个别成员时,往往会导致重复的初始化代码分散在各个构造函数里。使用委托构造函数能在一定程序上解决了这个问题,不过有时仍然需要这样的重复初始化,从而使用代码维护困难并损害可读性。
当前现状
您的类有多个构造函数,迫使你在每一个构造函数中重复数据成员的初始化代码。
解决方案
使用类成员初始化来一次性初始化数据会员。
初始化问题
在当代C + +中,只有整数类型的静态成员或者枚举常量才可以直接声明初始数据。例如:
- class A
- {
- static const int MAX=1024;
- public:
- A();
- //..
- };
然而,下面这个类是不允许的,因为b既不是一个整数类型的常量静态成员也不是一个常量枚举类型:
- class C
- {
- int b=1024; //error
- bool f;
- double d;
- //..
- };
由于这一限制,我们不得不在构造C类时重复初始化成员b:
- class C
- {
- int b;
- bool f;
- double d;
- public:
- C(): b(1024), f(false), d(0.0) {}
- C(bool flag) : b(1024), f(flag), d(0.0) {}
- C(bool flag, double dbl): b(1024), f(flag), d(dbl){}
- };
这种重复既费力而又容易出错。为什么不一次指定b的初始值?一个新的C++0x建议允许我们做,甚至更多。
类成员初始化
在解释什么是类成员初始化之前,我不得不澄清一下术语,以避免混淆。
成员初始化列表,它出现在构造函数的参数列表之后,以冒号开头:
- class A
- {
- int x;
- int y;
- public:
- A(): x(2), y(3){}
- };
initializer_list是C++09的一个类模板,定义于
- template
- class vector
- {
- public:
- vector(std::initializer_list
s); - };
- vector
vi={1,8,102,99};
类成员初始化是一个新的C++0x提案,不要和上述两个初始化结构混淆了。
类成员初始化语法看起来像这样:
- class D
- {
- public:
- int x=5; //类成员初始化, C++0x only
- int y(6); //另一种形式的初始化
- };
编译器会按概念把类成员初始化转换成类成员初始化列表。因此,上面声明的D类在编译时会转换成下面这个样子:
- class D
- {
- public:
- int x;
- D(): x(5), y(6) {}
- };
从编程者的角度来看,类成员初始化功能似乎并不像是一个显着的改善(除了语法更直观一点) 。然而,当你的类有多个构造函数时,它的优势就会变得明显起来。这里是一个使用类成员初始化的C类:
- class C
- {
- int b=1024;//c类成员初始化, C++0x
- bool f;
- double d;
- public:
- C(): f(false), d(0.0) {}
- C(bool flag) : f(flag), d(0.0) {}
- C(bool flag, double dbl): f(flag), d(dbl){}
- };
数据成员f和d出现在每一个构造函数的成员初始化列表中,在这之前,b只需要初始化一次,而不用构造函数操心。
默认和覆盖
类成员初始化能够做的比您刚才看到的更多。在前面的版本的C类里,前两个构造函数把d初始化为0.0,只有第三个构造函数把d初始化成了其它值。在这种情况下,您可以用类成员初始化指定默认值,并在必要时覆盖的初始化值:
- class C
- {
- int b=1024;
- bool f;
- double d=0.0; //d的默认值
- public:
- C(): f(false) {}//b 初始化为 1024, d 为 0.0
- C(bool flag) : f(flag) {} // 同上
- C(bool flag, double dbl): f(flag), d(dbl){} // 覆盖d的默认值
- };
构造函数的成员初始化列表中不包含成员d时就会使用默认的初始化-类成员初始化。因此,在前面的示例中,前两个构造函数将d初始化为0.0,第三个初始化为dbl。
你可以进一步简化构造函数:
- class C
- {
- int b=1024;
- bool f=false;
- double d=0.0;
- public:
- C(){} C(bool flag): f(flag) {}
- C(bool flag, double dbl): f(flag), d(dbl){}
- };
总之,只有需要覆盖默认初始化值时才应在构造函数的初始化列表中明确指出。请注意,没有初始化的数据成员将有一个不确定的值,因此:
- class G
- {
- public:
- std::string x("TEST"); //class member init for string
- int y;
- int z;
- G(): z(0){}//initialize x and z, y has an undefined value
- };
在本文写作之时,类成员初始化的提案有很大的机会被纳入到C++0x标准中,您可以在这里获得最新的各种支持C++0x的编译器。
- 使用类成员初始化特性简化构造代码
- 使用反射、特性简化代码
- 利用构造函数进行简化类初始化
- 使用静态构造函数初始化静态成员
- 使用构造函数初始化成员数组
- Java 代码块、成员变量初始化、构造函数初始化顺序
- 三角形类(在构造函数中使用参数初始化表对数据成员初始化)
- 三角形类的构造函数-使用参数初始化表对数据成员初始化
- java中类的静态代码块、构造代码块、构造方法、静态成员的初始化顺序详解
- java中类的静态代码块、构造代码块、构造方法、静态成员的初始化顺序详解
- C++构造函数对类成员变量初始化,使用初始化列表和构造函数内部直接赋值 的区别
- static代码块、成员变量初始化、构造方法执行顺序
- C++类使用默认构造函数时各数据成员的初始化
- Effective C# Item13:使用静态构造器初始化静态类成员
- 使用构造方法对student类的成员变量进行初始化
- 拷贝构造函数,也可以使用成员初始化列表语法
- 第3周-项目1-三角形类的构造函数-使用参数初始化表对数据成员初始化
- 使用初始化成员列表初始化数据与在构造函数中初始化数据
- Asp 时间函数详解
- 关于qtcpsocket连续读写,qthread continue write read
- 收藏微软面试智力题 (附答案)
- 有恒心的认真的去做一件事
- datagridview
- 使用类成员初始化特性简化构造代码
- C#2.0 DataGridView
- ValidateRequest 属性
- ORACLE警告日志简介
- 日志,对程序的排查错误很有用处
- create database手工新建数据库
- 魔方复原的编程实现
- Oracle 10g EXPDP和IMPDP使用说明
- 利用委托实现winform窗体间通信