侧边栏壁纸
  • 累计撰写 218 篇文章
  • 累计创建 59 个标签
  • 累计收到 5 条评论

委托构造和初始化列表

barwe
2022-07-23 / 0 评论 / 0 点赞 / 819 阅读 / 1,164 字
温馨提示:
本文最后更新于 2022-07-23,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

委托构造初始化列表 都用来帮助构造函数快速初始化成员。

委托构造

C++可以依据参数列表长度、顺序和类型的不同声明多个构造函数,多个构造函数可能会做一些重复的工作,这时通过调用同一个类的其它构造函数可以消除这种重复,即 将自己的一部分工作委托给其它的构造函数完成,调用其它构造函数的这个构造函数被称之为 委托构造函数 (Delegating Constructor)

class Person {
    int id;
    int gender;
    public:
    	Person(int _id, int _gender): id(_id), gender(_gender) {} // 1
    	Person(int _id): Person(_id, 1) {} // 2
    	Person(): Person(1, 1) {} // 3
}

上面的 Person 类定义了三个构造函数。

第一个构造函数有两个参数,使用 构造函数初始化列表 对类的两个成员进行初始化。

第二个构造函数只有一个参数,另一个是默认值,它将初始化任务委托给了第一个构造函数。

第三个构造函数两个参数都是默认值,它也将初始化任务委托给了第一个构造函数。

委托构造初始化列表 的位置都位于参数列表的后面,一个构造函数使用委托构造后就不能继续初始化其它的参数了,其它的初始化操作应该放在方法实现中用 赋值 的方式完成。

两个构造函数相互委托就会实现 委托环 导致编译报错,应该避免这种情况。

try ... catch可以捕获委托构造时被委托构造函数抛出的异常:

class Person {
    Person(int _id, int _gender): id(_id), gender(_gender) {}
    Person(int _id): try Person(_id, 1) {
        //...
    } catch (/*...*/) {
        //...
    }
}

另外,对于一个继承自父类的类,自己新增的构造函数也可以委托父类的构造函数:

class Shape {
    int edges;
    Shape(int _edges): edges(_edges) {}
}

class Square: public Shape {
    int w;
    Square(int _edges, int _w): Shape(_edges) {
        w = _w;
    }
}

初始化列表

构造函数中的初始化列表用来对实例的属性快速赋值,这一般与在构造函数实现中逐个赋值是等价的:

class Person {
    int _id;
    int _gender;
    // Person(int _id, int _gender): id(_id), gender(_gender) {}
    Person(int _id, int _gender) {
        id = _id;
        gender = _gender;
    }
}

然而对于不能赋值的成员,例如 const 成员或者引用类型的成员,只能使用初始化列表进行初始化。

对多个成员进行初始化时,编译器按照成员的声明顺序,而不是在初始化列表中的顺序进行初始化。

0

评论区