C++之派生類的拷貝構造與賦值運算子過載
阿新 • • 發佈:2019-01-31
這裡只說一下為什麼派生類在拷貝構造器和賦值運算子過載中一些注意語法:
一、派生類的拷貝構造器
1.派生類的拷貝構造器跟普通構造器一樣,若沒有自定義生成,編譯器會自動生成拷貝構造器,自動呼叫父類的拷貝構造器(不管父類的拷貝構造是否自定義或編譯器自動生成)。
2.若派生類的拷貝構造器自定義生成,則一定要顯示呼叫父類的拷貝構造器(不管父類的拷貝構造器是否自定義或編譯器自動生成),否則編譯可以通過,But拷貝不正確。
3.當自定義派生類的拷貝構造時注意顯示呼叫父類的拷貝構造器的位置:在初始化列表(即引數列表的位置)。原因是:派生類能全盤繼承父類的任何東西,除了構造器和析構器,故不能函式體中顯式呼叫父類的拷貝構造。
二、派生類的賦值運算子過載
1.派生類的賦值運算子過載與派生類的拷貝構造器的前兩條類似;
2.當自定義派生類的賦值運算子過載時注意呼叫父類的賦值運算子過載函式前要加上父類的域名,因為兩個類的賦值運算子過載函式名都為:
operator=
這麼個東西,子類與父類如果有函式同名的函式,不管返回值和引數是什麼,都會發生shadow現象,也就是說子類的函式隱藏了父類的同名函式,子類只知道自己有這麼個函式,就不曉得父類其實也有個同名的函式。為了防止這種命名衝突現象,在繼承過程中,父類的資料成員和成員函式會帶著父類的域名一起被繼承,而不是單純的繼承資料成員和成員函式。
下面舉個例子:
class Student
{
public:
Student(char* name = "", int age = 0, float score = 0)
{
int len = strlen(name);
this->name = new char[len + 1];
strcpy(this->name, name);
this->age = age;
this->score = score;
}
~Student(){
delete []name;
}
Student(const Student & another){
delete []name;
int len = strlen(another.name);
name = new char[len + 1];
strcpy(name, another.name);
age = another.age;
score = another.score;
}
Student& operator=(const Student & another){
if(this == &another)
return *this;
delete []name;
int len = strlen(another.name);
name = new char[len + 1];
strcpy(name, another.name);
age = another.age;
score = another.score;
return *this;
}
void dis(){
cout << "name: " << name << endl;
cout << "age: " << age << endl;
cout << "score: " << score << endl;
}
private:
char* name;
int age;
float score;
};
class GraduateStudent: public Student
{
public:
GraduateStudent(char* name = "", int age = 0, float score = 0, double salary = 0):Student(name, age, score), salary(salary){};
GraduateStudent(const GraduateStudent & another):Student(another){
salary = another.salary;
}
GraduateStudent& operator=(const GraduateStudent& another){
if(this == &another)
return *this;
Student::operator =(another);
salary = another.salary;
}
void dis(){
Student::dis();
cout << "salary: " << salary << endl;
}
private:
double salary;
};
int main()
{
Student s1("jack", 25, 130);
s1.dis();
cout << "-------------------" << endl;
GraduateStudent gs("marray", 30, 150, 3000);
gs.dis();
cout << "-------------------" << endl;
GraduateStudent gs_cpy(gs);
gs_cpy.dis();
GraduateStudent gs_equal;
cout << "-------------------" << endl;
gs_equal = gs_cpy;
gs_equal.dis();
return 0;
}
結果如下:
這裡對dis()函式也做了shadow現象的處理,加了函式域名,另外不論是拷貝構造還是賦值運算子過載都採用的深拷貝,當然預設都是淺拷貝(也叫等位拷貝)。