C++进阶:继承(四)

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

一、继承中的拷贝构造函数

✔ 测试用例一:

#include<iostream>
#include<string>
using namespace std;

class Person
{
public:
	Person(const char* name = "dancebit")
		: _name(name)
	{
		cout << "Person(const char* name = \"dancebit\")" << endl;
	}
	Person(const Person& p)
		: _name(p._name)
	{
		cout << "Person(const Person& p)" << endl;
	}
	Person& operator=(const Person& p)
	{
		cout << "Person& operator=(cconst Person& p)" << endl;
		if (this != &p)
			_name = p._name;

		return *this;
	}
	~Person()
	{
		cout << "~Person()" << endl;
	}
protected:
	string _name;
	int a;
};
class Student : public Person
{
public:
	Student(const char* name, int id, const char* address)
		: Person(name)
		, _id(id)
		, _address(address)
	{}
	Student(const Student& s)
		//: Person(s)//切片行为
		//, _id(s._id)
		//, _address(s._address)

		: _id(s._id)//不显示的调用父类的拷贝构造
		, _address(s._address)
	{}

private:
	int _id;
	string _address;
};

int main()
{
	Student s1("DANCEBIT", 1, "China");

	Student s2(s1);

	return 0;
}
  • 对于子类的拷贝构造,我们不写,编译器会默认生成。它针对 a) 内置类型成员完成值拷贝; b) 自定义类型成员,调用它的拷贝构造; c) 继承的父类成员作为一个整体,调用父类的拷贝构造;

    在这里插入图片描述

    在这里插入图片描述

  • 子类写了拷贝构造,子类就要显示的调用父类的拷贝构造,这里把子类对象里父类的那一部分取出来,本质就是切片行为 (这里把子类对象 s2 传给父类的引用,而父类仅仅使用了 _name)。

    但是实际上这里的拷贝构造没必要自己实现,因为这里一般情况下默认的拷贝构造就足够了,但是如果子类中有一个指针指向一块动态开辟的空间,存在深浅拷贝问题时就需要自己实现。

  • 如果子类中的拷贝构造不显示的调用父类的拷贝构造,那么便不会调用父类的拷贝构造,而是调用了默认的构造函数,因为拷贝构造也是构造,构造函数规定在初始化列表阶段,如果你不调用自定义类型,那就调用它的默认构造。

    在这里插入图片描述

二、继承与友元

✔ 测试用例二:

#include<iostream>
#include<string>
using namespace std;

class Student;
class Person
{
public:
	friend void Display(const Person& p, const Student& s);//友元
protected:
	string _name; 
};
class Student : public Person
{
	//friend void Display(const Person& p, const Student& s);//友元 
protected:
	int _stuNum; 
};
void Display(const Person& p, const Student& s) {
	cout << p._name << endl;
	cout << s._stuNum << endl;
}
void main()
{
	Person p;
	Student s;
	Display(p, s);
}
  • 友元关系不能被继承,也就是说基类友元不能访问子类私有和保护成员。解决方法就是在派生类中写友元。

猜你喜欢

转载自juejin.im/post/7125947957391654926