类的构造和析构
类的构造和析构#
-
类对象不能用列表初始化是因为数据访问状态为私有。
-
如果将访问状态改为公有,那么就可以使用大括号初始化的方法。但是违背了数据隐藏的初衷。
-
声明和定义构造函数
- 声明,其中可以包含默认参数
- Stock(const string & co, long n = 0, double pr = 0.0);
- 定义
- Stock::Stock(const string & co, long n, double pr)
- {
- ...
- }
- 为避免成员名和参数名混乱,常见的做法是在成员名前加m_前缀或加_后缀。
-
使用构造函数
- c++提供两种使用构造函数来初始化对象的方式。第一种是显式的调用构造函数。
- Stock food = Stock("yang", 29, 1.2);
- 另一种是隐式的调用
- Stock food("yang", 29, 2.1);
- 使用new分配内存时,c++都使用构造函数。在这种情况下,该对象没有名字,但可以使用指针来管理对象。
- Stock *food = new Stock("yang", 29, 1.2);
-
默认构造函数
- 默认构造函数是在未提供显式初始值时,用来创建对象的构造函数。
- Stock food;
- 当且仅当没有定义构造函数时,编译器才会提供默认构造函数。
- 为类定义了构造函数后,就必须提供默认构造函数。否则该声明会出错。Stock food;
- 定义默认构造函数的方式有两种
- 一种是给已有的构造函数所有参数提供默认值。
- Stock(const string& co = "yang", int n = 0, double pr = 0.0);
- 另一种方式是通过函数重载来定义另一个构造函数。一个没有参数的构造函数
- Stock();
- 由于只能有一个默认构造函数,因此不要同时采用这两种方式。通常应该初始化所有的成员。
-
析构函数
- 对象过期时,程序将自动调用一个特殊的成员函数。析构函数该函数将完成所有的清理工作。
- 如果创建的是静态存储类对象,则其析构函数将在程序结束时自动被调用。
- 如果创建的是自动存储类对象,析构函数将在程序执行完代码块时自动被调用。
- 如果对象通过new创建,则它将驻留在栈内存或自由存储区中。当使用delete释放内存时,析构函数自动调用。
- 程序可以创建临时对象完成特定操作,程序将在结束对该对象的使用时自动调用析构函数。
- 如果没有定义析构函数,编译器将隐式的声明一个默认析构函数。
-
创建对象
- 创建一个Stock对象stock1并且赋初值。
- Stock stock1("yang", 12, 20.0);
- c++标准允许编译器使用两种方式来执行下面的语法。
- Stock stock2 = Stock("yang", 12, 20.1);
- 第一种和前面的语句的行为一样。第二种是允许创建一个临时对象,然后将该临时对象复制到stock2中。复制完后调用临时对象的析构函数。
- 下述语句是赋值与初始化语句不一样。下面的语句会创建临时对象。
- stock3 = Stock("yang", 12, 23.1);
-
c++11列表初始化
- 只要提供与某个构造函数的参数列表匹配的内容,并用大括号括起来。
- Stock stock = {"yang", 12, 12.1};
- Stock stock2 {"yang"};
- Stock stock3 {};
-
const成员函数
- const Stock stock = Stock("yang");
- stock.show();
- 上述语句中编译器将会拒绝第二句。因为show方法中有可能会修改stock对象。
- 如果希望编译器通过,需要一种新的语法。
- void show() const;//声明
- void Stock::show() const;//定义
- 只要方法不修改调用对象,就应该将其声明为const。
-
构造函数只有一个参数时,允许使用赋值语法将对象初始化为一个值。这种特性可能导致出现一些问题,后面介绍可以关闭这种特性。