1006继承04继承中构造和析构顺序、继承同名成员处理方式

99 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

1 继承中构造和析构顺序

问题:当你创建一个子类对象,是先有个子类对象还是父类对象?是先析构了子类对象还是父类对象? 子类继承父类后,当创建子类对象,也会调用父类的构造函数

示例:

#include<iostream>
using namespace std;
class Fat
{
public:
	Fat()
	{
		cout << "Fat的构造函数" << endl;
	}
	~Fat()
	{
		cout << "Fat的析构函数" << endl;
	}
};

//私有继承
class Son :private Fat
{
public:
	Son()
	{
		cout << "Son的构造函数" << endl;
	}
	~Son()
	{
		cout << "Son的析构函数" << endl;
	}
};

void test()
{
	Fat fat;
}
int main() {

	test();

	system("pause");

	return 0;
}

输出:

Fat的构造函数 Fat的析构函数 请按任意键继续. . .


void test()
{
	Son son;
}

输出: Fat的构造函数 Son的构造函数 Son的析构函数 Fat的析构函数 请按任意键继续. . .

总结:继承中的构造和析构的顺序如下: 先构造父类在构造子类;先析构子类,再析构父类。 继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反

2 继承同名成员处理方式

问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢? 同名成员属性处理方式: 如果出现同名,直接访问就访问的是子类的,如果想通过子类访问父类继承下来的对象就需要加上作用域。 同名函数属性的处理方式 直接调用,调用的就是子类的

  • 访问子类同名成员 直接访问即可
  • 访问父类同名成员 需要加作用域同名成员,加上作用域就可以调用父类的同名对象。如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏父类中所有的同名成员函数;如果像访问到父类中被隐藏的同名成员函数,需要加上作用域。

示例:

#include<iostream>
using namespace std;
class Fat
{
public:
	Fat()
	{
		a = 1;
	}
	int a;
};

//私有继承
class Son :public Fat
{
public:
	Son()
	{
		b = 1;
	}
	int b;
};

void test()
{
	Son son;
	cout << "利用子类对象访问父类数据:a = " << son.a << endl;
}
int main() {

	test();

	system("pause");

	return 0;
}

输出:

利用子类对象访问父类数据:a = 1 请按任意键继续. . .

class Son :public Fat
{
public:
	Son()
	{
		a = 2;
	}
	int a;
};

输出:

利用子类对象访问父类数据:a = 2 请按任意键继续. . .

void test()
{
	Son son;
	cout << "利用子类对象出现同名,直接访问的是子类对象:a = " << son.a << endl;
	cout << "利用子类对象加作用域访问父类数据:a = " << son.Fat::a << endl;

}

输出:

利用子类对象出现同名,直接访问的是子类对象:a = 2 利用子类对象加作用域访问父类数据:a = 1 请按任意键继续. . .

#include<iostream>
using namespace std;
class Fat
{
public:
	void func()
	{
		cout << "调用Fat中的func" << endl;
	}
};

//私有继承
class Son :public Fat
{
public:
	Son()
	{
		a = 2;
	}
	int a;
};

void test()
{
	Son son;
	son.func();
}
int main() {

	test();

	system("pause");

	return 0;
}

输出:

调用Fat中的func 请按任意键继续. . .

class Son :public Fat
{
public:
	void func()
	{
		cout << "调用Son中的func" << endl;
	}
};
调用Son中的func
请按任意键继续. . .

void test()
{
	Son son;
	son.Fat::func();
}

输出:

调用Fat中的func 请按任意键继续. . .

总结:

  1. 子类对象可以直接访问到子类中同名成员
  2. 子类对象加作用域可以访问到父类同名成员
  3. 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数