本文共 2413 字,大约阅读时间需要 8 分钟。
1、构造函数概念
类通过一个或几个特殊的成员函数来控制其对象的初始化过程,初始化类对象的数据成员,这些函数叫构造函数!
构造函数的名字和类名相同,构造函数没有返回类型。不同的构造函数之间必须在参数数量和类型上有所区别。
2、默认构造函数
编译器创建的构造函数又被称为——合成的默认构造函数。
对于一个普通的类来说,最好自己定义自己的默认构造函数。
A.经验规则:如果一个类在某种情况下需要控制对象的初始化,那么该类很可能在所有情况下都需要控制。而只有当类没有声明任何构造函数时,编译器才会自动生成默认构造函数。
B.另外,如果定义在块中的内置类型或复合类型的对象被默认初始化,则它们的值是未定义 的。 C.如果一个类中含有其他类的成员,而且这个其他类的成员类型没有默认构造函数,吗么编译器将无法初始化构造函数。3、=default
在C++11新标准中,如果我们需要默认的行为,那么可以通过在参数列表后面分号之前写上=default来要求编译器生成构造函数。这个构造函数的目的在于:我们既需要其他形式的构造函数,又需要默认的构造函数。
4、构造函数初始值列表
它负责为新创建的对象的一个或几个数据成员赋初值。构造函数初始值是成员名字的一个列表,每个括号后面紧跟括起来的成员初始值,不同成员的初始化用逗号隔开。
class Sales_data {public: Sales_data() = default; Sales_data(const std::string &s): bookNo(s) { } Sales_data(const std::string &s): bookNo(s), units_sold(0), revenue(0.0) { } Sales_data(const std::string &s, unsigned n, double p): bookNo(s), units_sold(n), revenue(p*n) { } //接受三个实参,使用这些实参初始化数据成员,然后结束工作 Sales_data(std::istream &); std::string isbn() const { return bookNo; } Sales_data& combine(const Sales_data&); double avg_price() const;private: std::string bookNo; unsigned units_sold = 0; double revenue = 0.0;};特别提醒:如果成员是const、引用或者属于某种其他类类型且该类灭有定义默认的构造函数时,我们必须通过——构造函数初始值列表为这些成员提供初值。如果没有在构造函数的初始值列表中显示地初始化成员,则该成员将在构造函数体之前就执行默认初始化。随着构造函数体的一开始执行,初始化就完成了。
class ConstRef{public: ConstRef(int ii);private: int i; const int ci; //常量 int &ri; //引用};//错误:成员ci和ri必须被初始化ConstRef::ConstRef(int ii){ //就对象的数据成员而言,初始化和赋值是有区别的。如果没有在构造函数的初始值列表中显示地初始化成员,则该成员将在构造函数体之前就执行默认初始化。 //在此是赋值 i = ii; //正确 ci = ii; //错误:不能给const赋值 ri = i; //错误:ri没有被初始化}//初始化const或者引用类型的数据成员的唯一机会就是:通过构造函数初始值列表。//因此需要显示地初始化const和引用数据成员,而不是去赋值。该构造函数的正确形式如下:ConstRef::ConstRef(int ii) :i(ii), ci(ii), ri(ii) { }5、委托构造函数
顾名思义,该构造函数把自己的一些(或全部)初始化职责委托给其他构造函数来完成。当一个构造函数委托给另外一个构造函数时,受委托的构造函数的初始值列表和函数体被依次执行。控制权先由受委托的构造函数掌控,然后在交还给委托构造函数的函数体(如果有的话)。
6、转换构造函数
能通过一个实参调用的构造函数,定义了一条从构造函数的参数类型向类类型隐式转换的规则。
可以通过将构造函数声明为explicit,来加以阻止构造函数的隐式转换。只能在类内声明构造函数时使用explicit关键字,在类外定义时不应该重复。关键字explicit只对一个实参的构造函数有效。需要多个实参的构造函数不能用于执行隐式转换,所以无需将这些构造函数指定为explicit的。
explicit的构造函数只能用于直接初始化:
class Sales_data{public: explicit Sales_data(const string &s) :bookNo(s) {}private: string bookNo; unsigned units_sold = 0; double revenue = 0.0;};string null_book = "9-999-999-999";Sales_data item1(null_book); //正确:直接初始化Sales_data item2 = null_book; //错误:不能将explicit构造函数用于拷贝形式的初始化过程7、聚合类
当一个类满足以下条件时,我们说它是聚合的:
A.所有成员都是public的;
B.没有定义任何构造函数; C.没有类内初始值; D.没有基类,也没有virtual函数;转载地址:http://qzopi.baihongyu.com/