6个默认成员函数,“默认”的意思就是指我们不写,编译器会变成我们自动生成一个,那么在派生类中,这几个成员函数是如何生成的呢?
- 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。
- 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
- 派生类的operator=必须要调用基类的operator=完成基类的复制。
- 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。
- 派生类对象初始化先调用基类构造再调派生类构造。
- 派生类对象析构清理先调用派生类析构再调基类的析构。
class Person
{
public:
Person(const char* name = "zd")
: _name(name)
{
cout << "Person()" << endl;
}
Person(const Person& p)
: _name(p._name)
{
cout << "Person(const Person& p)" << endl;
}
Person& operator=(const Person& p)
{
cout << "Person operator=(const Person& p)" << endl;
if (this != &p)
_name = p._name;
return *this;
}
~Person()
{
cout << "~Person()" << endl;
}
protected:
string _name; //姓名
};
class Student : public Person
{
public:
//构造函数(先父后子)
Student(const char* name, int num)
: Person(name) //子类不能自己对父类成员进行初始化
, _num(num)
{
cout << "Student()" << endl;
}
//拷贝构造
Student(const Student& s)
: Person(s) //切片:父类会自己切下子类中属于自己的部分进行拷贝构造
, _num(s._num)
{
cout << "Student(const Student& s)" << endl;
}
//赋值重载
Student& operator=(const Student& s)
{
cout << "Student operator=(const Student& p)" << endl;
if (this != &s)
{
Person::operator= (s);
_num = s._num;
}
return *this;
}
//析构函数(先子后父)
~Student()
{
cout << "~Student()" << endl;
}
protected:
int _num; //学号
};
void Test()
{
Student s1("Jack", 18);
Student s2(s1);
Student s3("Rose", 17);
s1 = s3;
}