当前位置:嗨网首页>书籍在线阅读

09-对类的修改

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

18.1.7 对类的修改

为简化和扩展类设计,C++11做了多项改进。这包括允许构造函数被继承和彼此调用、更佳的方法访问控制方式以及移动构造函数和移动赋值运算符,这些都将在本章介绍。下面先来复习本书前面介绍过的改进。

1.显式转换运算符

有趣的是,C++很早就支持对象自动转换。但随着编程经验的积累,程序员逐渐认识到,自动类型转换可能导致意外转换的问题。为解决这种问题,C++引入了关键字explicit,以禁止单参数构造函数导致的自动转换:

class Plebe
{
    Plebe(int); // automatic int-to-plebe conversion
    explicit Plebe(double); // requires explicit use
    ...
};
...
Plebe a, b;
a = 5;          // implicit conversion, call Plebe(5)
b = 0.5;        // not allowed
b = Plebe(0.5); // explicit conversion

C++11拓展了explicit的这种用法,使得可对转换函数做类似的处理(参见第11章):

class Plebe
{
...
// conversion functions
    operator int() const;
    explicit operator double() const;
    ...
};
...
Plebe a, b;
int n = a;     // int-to-Plebe automatic conversion
double x = b;  // not allowed
x = double(b); // explicit conversion, allowed

2.类内成员初始化

很多首次使用C++的用户都会问,为何不能在类定义中初始化成员?现在可以这样做了,其语法类似于下面这样:

class Session
{
    int mem1 = 10;         // in-class initialization
    double mem2 {1966.54}; // in-class initialization
    short mem3;
public:
    Session(){}                                                      // #1
    Session(short s) : mem3(s) {}                                    // #2
    Session(int n, double d, short s) : mem1(n), mem2(d), mem3(s) {} // #3
...
};

可使用等号或大括号版本的初始化,但不能使用圆括号版本的初始化。其结果与给前两个构造函数提供成员初始化列表,并指定mem1和mem2的值相同:

Session() : mem1(10), mem2(1966.54) {}
Session(short s) : mem1(10), mem2(1966.54), mem3(s) {}

通过使用类内初始化,可避免在构造函数中编写重复的代码,从而降低了程序员的工作量、厌倦情绪和出错的机会。

如果构造函数在成员初始化列表中提供了相应的值,这些默认值将被覆盖,因此第三个构造函数覆盖了类内成员初始化。