一.序
C++类的6个默认的成员函数包括:构造函数、析构函数、拷贝构造函数、赋值运算符重载函数、取地址操作符重载函数、const修饰的取地址操作符重载函数。
这篇文章先列出构造函数和析构函数,其他后续更新在其它博文。
二.详解构造函数
1.定义
数据成员多为私有的,要对它们进行初始化,必须用一个公有函数来进行。同时这个函数应该在且仅在定义对象时自动执行一次。称为构造函数(constructor)
2.特征
1.函数名与类名相同。
2.构造函数无函数返回类型说明。注意是没有而不是void,即什么也不写,也不可写void!实际上构造函数有返回值,返回的就是构造函数所创建的对象,见5.5节。
3.在程序运行时,当新的对象被建立,该对象所属的类的构造函数自动被调用,在该对象生存期中也只调用这一次。
4.构造函数可以重载。严格地讲,说明中可以有多个构造函数,它们由不同的参数表区分,系统在自动调用时按一般函数重载的规则选一个执行。
5.构造函数可以在类中定义,也可以在类外定义。
6. 如果类说明中没有给出构造函数,则C++编译器自动给出一个缺省的构造函数:
类名(void) {}
但只要我们定义了一个构造函数,系统就不会自动生成缺省的构造函数。
只要构造函数是无参的或者只要各参数均有缺省值的,C++编译器都认为是缺省的构造函数,并且缺省的构造函数只能有一个 。
如果对象的数据成员全为公有的,也可以在对象名后加“=”加“{}”,在花括号中顺序填入全体数据成员的初始值.
7.缺省的构造函数和无参的构造函数只能有一个,否则调用的时候就会产生冲突。
8.没有this指针。因为构造函数才是创建对象的,没有创建对象就不会有对象的地址。
3.Attention
1.缺省的构造函数包括两种,
系统产生的/用户定义的
用户定义的就是各参数均有缺省值的
缺省的构造函数只能有一个,举例:
#include<iostream>
using namespace std;
class Test
{
public:
Test(int d = 0) : data(d)
{}
Test()
{}
private:
int data;
};
void main()
{
Test t;//程序会报错:类 "Test" 包含多个默认构造函数
Test t1();//程序不报错,但不能达到实例化出t1的目的,见2的分解
}
2.Test t1();
这在程序编译时是不会报错的,但是并不能实例化出t1对象,原因如下:
Test t1();这被编译器当作一个参数列表为空,返回值是Test类型的函数的声明。
二.详解析构函数
1.定义
当一个对象定义时,C++自动调用构造函数建立该对象并进行初始化,那么当一个对象的生命周期结束时,C++也会自动调用一个函数注销该对象并进行善后工作,这个特殊的成员函数即析构函数(destructor):
2.特征
- 析构函数名与类名相同,但在前面加上字符‘~’,如
~CGoods()。- 析构函数无函数返回类型,与构造函数在这方面是一样的。但析构函数不带任何参数。
- 一个类有一个且只有一个析构函数,这与构造函数不同。析构函数可以缺省。
- 对象注销时,系统自动调用析构函数。
- 注意析构函数体内并不是删除对象,而是做一些清理工作。(比如我们在构造函数中动态开辟过一段空间,函数结束后需要释放,而系统自动生成的析构函数才不管内存释放呢,所以需要人为地写出析构函数
3.Attention
1.析构函数析构对象的顺序与构造函数构造对象的顺序相反,举例:
#include<iostream>
using namespace std;
class Test
{
public:
Test(int d = 0) : data(d)
{
cout<<"Create new object:"<<this<<endl;
}
~Test()
{
cout<<"Free object:"<<this<<endl;
}
private:
int data;
};
void main()
{
Test t;
Test t1;
Test t2;
}
2.析构函数不允许带参数,不允许有返回值。
三.关于构造与析构顺序的解答
1.无论是构造还是析构,都是在栈上构造对象,在栈上注销对象。所以是在对栈进行操作。所以先构造的对象在高地址,也就是靠近栈底;栈顶元素先出栈,所以后构造的对象先释放。这就造成了这样的现象
2.图解