C++——继承中的构造函数 – 作者:Johnson666

1.继承中的构造函数访问顺序

由于父类和子类中都有构造函数和析构函数,那么子类对象在创建时父类先进行构造,还是子类先进行构造呢?同样在子类对象释放时,是父类先进行释放,还是子类先进行释放呢?这都有个先后顺序的问题。答案是当从父类派生一个子类并声明一个子类的对象时,它将先调用父类的构造函数,然后调用当前类的构造函数来创建对象;在释放子类对象时,先调用的是当前类的析构函数,然后是父类的析构函数。下面来个例子:

#include<iostream>
using namespace std;

class Employee
{
public:
	int id;
	char name[100];
	char depart[100];
	Employee()
	{
		cout << "Employee类构造函数被调用" << endl;
	}
	~Employee()
	{
		cout << "Employee类析构函数被调用" << endl;
	}
};

class Operator:public Employee
{
public:
	 char password[100];
	 Operator()
	 {
		 strcpy(name,"Johnson666");
		 cout << "Operator类构造函数被调用" << endl;
	 }
	 ~Operator()
	 {
		 cout << "Operator类析构函数被调用" << endl;
	 }
};

int main()
{
	Operator o;
	cout << o.name << endl;
	return 0;
}

结果:
image.png
从图中可以看出,在定义Operator类对象时,首先调用的是父类Employee的构造函数,然后是Operator类的构造函数。子类对象的释放过程则与其构造过程恰恰相反,先调用自身的析构函数,然后再调用父类的析构函数。
最后简单总结一句话:先构造后析构,后构造先析构。

2.子类显式调用父类构造函数

当父类含有带参数的构造函数时,创建子类会调用它吗?答案是通过显式方式才可以调用。
无论创建子类对象时,调用的是哪种子类构造函数,都会自动调用父类默认构造函数。若想使用父类带参数的构造函数,则需要显式的方式:

#include<iostream>
using namespace std;

class Employee
{
public:
	int id;
	char Name[100];
	char depart[100];
	Employee(char name[])
	{
		strcpy(Name,name);
		cout << Name << "调用了Employee类带参数的构造函数" << endl;
	}
	Employee()
	{
		strcpy(Name,"Johnson666");
		cout << Name << "Employee类无参构造函数被调用" << endl;
	}
	~Employee()
	{
		cout << "Employee类析构函数被调用" << endl;
	}
};

class Operator:public Employee
{
public:
	 char password[100];
	 Operator(char name[]):Employee(name)  //显式调用父类带参数的构造函数
	 {
		 cout << "Operator类构造函数被调用" << endl;
	 }
	 Operator():Employee("Johnson")  //显式调用父类带参数的构造函数
	 {
		 cout << "Operator类析构函数被调用" <<endl;
	 }
};

int main()
{
	Operator o1;
	Operator o2("xixixi");
	return 0;
}

结果:
image.png
在父类无参构造函数中初始化成员字符串数组Name为”Johnson666“.从结果上来看,子类对象创建时没有调用父类无参构造函数,调用的是带参数的构造函数。

注意:
当父类只有带参数的构造函数时,子类必须以显式方法调用父类带参数的构造函数,否则编译会出现错误。

拓展

稍微提下:如果子类中定义了一个和父类一样的成员函数,那么一个子类对象是调用子类中的成员函数。如果你想访问父类的成员函数,需要显式使用父类名。比如:
有一个父类Employee和子类Operator

Operator o;
o.outputName();  //调用子类Operator类的outputName成员函数
o.Employee::outputName();  //调用父类Employee类的outputName成员函数

来源:freebuf.com 2021-05-20 21:00:25 by: Johnson666

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论