在一个类中,至少有六个默认的成员函数,所谓的“默认”就是,我们不写,编译器自动给我们生成。
class Person
{
public:
Person(string name = "jason")
:_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;
}
private:
string _name;
};
class Student:public Person
{
public:
Student(string name = "jason", int num = 18)
: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;
}
private:
int _num;
};
void Text()
{
Student s1("james", 18);
Student s2(s1);
Student s3("carry", 19);
s1 = s3;
}
注意:
- 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函 数,则必须在派生类构造函数的初始化列表阶段显示调用。
- 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
- 派生类的operator=必须要调用基类的operator=完成基类的复制。
- 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类 对象先清理派生类成员再清理基类成员的顺序。
- 派生类对象初始化先调用基类构造再调派生类构造。
- 派生类对象析构清理先调用派生类析构再调基类的析构