派生类的赋值运算符重载【C++继承】
- 派生類的賦值符重載
- 情況分析
- 父類和子類都使用系統默認提供的賦值運算符重載
- 父類自實現賦值運算符重載,子類使用系統默認提供的賦值運算符重載。
- 父類使用系統默認提供的賦值運算符重載,子類自實現賦值運算符重載。
- 父類和子類都自實現賦值運算符重載
- 父類顯式調用
- 語法
- 賦值順序
- 圖示
- 注解
- 代碼演示
- 內嵌子對象
- 子類和內嵌子對象都使用系統默認提供的賦值運算符重載。
- 子類使用系統默認提供的賦值運算符重載,內嵌子對象類自實現賦值運算符重載函數。
- 子類是自實現賦值運算符重載函數,內嵌子對象使用系統默認提供的賦值運算符重載。
- 子類和內嵌子對象類都自實現賦值運算符重載函數。
- 內嵌子對象顯式調用
- 實戰操作
- 實戰:使用系統默認的賦值運算符重載函數實現派生類的淺賦值。
- 實戰:自實現顯式調用賦值運算符重載函數實現派生類的淺賦值。
- 實戰:自實現顯式調用賦值運算符重載函數實現派生類的深賦值。
派生類的賦值符重載
賦值運算符函數,不是構造器,可以看作普通函數去繼承。
情況分析
父類和子類都使用系統默認提供的賦值運算符重載
代碼演示:
#include <iostream> using namespace std;class A { public:A(string x = " "){a = x;cout << "A()" << endl;}string a; };class B:public A { public:B(string x , string y):A(x){b = y;cout << "B()" << endl;}string b; };int main() {B b("b1","b2");B bb("bb1","bb2"); bb = b; //使用系統默認提供的賦值運算符重載cout << "bb.a:" << bb.a << endl;cout << "bb.b:" << bb.b << endl;return 0; }運行結果:
父類和子類都是系統默認的賦值運算符重載,父類和子類的賦值運算符重載都調用成功。
父類自實現賦值運算符重載,子類使用系統默認提供的賦值運算符重載。
代碼演示:
#include <iostream>using namespace std;class A { public:A(string x = " "){a = x;cout << "A()" << endl;}A & operator=(const A & another){if (this == &another) //判斷是否是自賦值return *this;this->a = another.a;cout << "A & operator=(const A & another)" << endl;return *this;}string a; };class B:public A { public:B(string x , string y):A(x){b = y;cout << "B()" << endl;}string b; };int main() {B b("b1","b2");B bb("bb1","bb2");bb = b;cout << "bb.a:" << bb.a << endl;cout << "bb.b:" << bb.b << endl;return 0; }運行結果:
父類自實現的賦值運算符重載函數和系統默認提供的賦值運算符重載函數的功能相同,只不過多了一個cout輸出語句。
先調用父類自實現的賦值運算符重載函數,然后子類調用系統默認提供賦值運算符重載函數。
父類使用系統默認提供的賦值運算符重載,子類自實現賦值運算符重載。
代碼演示:
#include <iostream>using namespace std;class A { public:A(string x = " "){a = x;cout << "A()" << endl;}string a; };class B:public A { public:B(string x , string y):A(x){b = y;cout << "B()" << endl;}B & operator=(const B& another){if (this == &another) //判斷是否是自賦值return *this;cout << "B & operator=(const B & another)" << endl;this->b = another.b;return *this;}string b; };int main() {B b("b1","b2");B bb("bb1","bb2");bb = b;cout << "bb.a:" << bb.a << endl;cout << "bb.b:" << bb.b << endl;return 0; }運行結果:
父類系統默認,子類自實現賦值運算符重載的時候,調用父類的構造器,然后調用子類自實現賦值運算符重載。失去了賦值的意義。
父類和子類都自實現賦值運算符重載
代碼演示:
#include <iostream>using namespace std;class A { public:A(string x = " "){a = x;cout << "A()" << endl;}A& operator=(const A& another){this->a = another.a;cout << "A & operator=(const A & another)" << endl;return *(this);}string a; };class B:public A { public:B(string x , string y):A(x){b = y;cout << "B()" << endl;}B & operator=(const B& another){if (this == &another) //判斷是否是自賦值return *this;cout << "B & operator=(const B & another)" << endl;this->b = another.b;return *this;}string b; };int main() {B b("b1","b2");B bb("bb1","bb2");bb = b;cout << "bb.a:" << bb.a << endl;cout << "bb.b:" << bb.b << endl;return 0; }運行結果:
父類和子類都自實現賦值運算符重載函數的時候,調用父類的構造器,然后調用子類自實現賦值運算符重載。失去了賦值的意義。
父類顯式調用
賦值運算符重載已經被繼承,可以在子類直接調用父類的賦值運算符重載函數。
語法
子類 & 子類::operator=(const 子類 & another) { ...父類::operator =(another); // 顯示調用父類的賦值運算符重載 ... }賦值順序
圖示
注解
代碼演示
#include <iostream> using namespace std;class A { public:A(string x = " "){a = x;cout << "A()" << endl;}A & operator=(const A & another){if (this == &another) //判斷是否是自賦值return *this;this->a = another.a;cout << "A & operator=(const A & another)" << endl;return *this;}string a; };class B:public A { public:B(string x , string y):A(x){b = y;cout << "B()" << endl;}B & operator=(const B & another){if (this == &another) //判斷是否是自賦值return *this;cout << "B & operator=(const B & another)" << endl;A::operator=(another); //繼承賦值運算符重載函數this->b = another.b;return *this;}string b; };int main() {B b("b1","b2");B bb("bb1","bb2");bb = b;cout << "bb.a:" << bb.a << endl;cout << "bb.b:" << bb.b << endl;return 0; }運行結果:
上面代碼中:
B & operator=(const B& another){if (this == &another) //判斷是否是自賦值return *this;cout << "B & operator=(const B & another)" << endl;A::operator=(another); //繼承賦值運算符重載函數this->b = another.b;return *this;}A::operator=(another); 必須加上A:: 作用域是不能省略的。
否則B的賦值運算符重載函數就會和里面的operator=(another);同名,就是自己調用自己實現了遞歸。
代碼演示:
#include <iostream> using namespace std;class A { public:A(string x = " "){a = x;cout << "A()" << endl;}A& operator=(const A& another){if (this == &another) //判斷是否是自賦值return *this;this->a = another.a;cout << "A & operator=(const A & another)" << endl;return *this;}string a; };class B:public A { public:B(string x , string y):A(x){b = y;cout << "B()" << endl;}B & operator=(const B& another){if (this == &another) //判斷是否是自賦值return *this;cout << "B & operator=(const B & another)" << endl;operator=(another); //繼承賦值運算符重載函數this->b = another.b;return *this;}string b; };int main() {B b("b1","b2");B bb("bb1","bb2");bb = b;cout << "bb.a:" << bb.a << endl;cout << "bb.b:" << bb.b << endl;return 0; }運行結果:
就會進入死循環。
內嵌子對象
子類和內嵌子對象都使用系統默認提供的賦值運算符重載。
代碼演示:
#include <iostream> using namespace std;class C { public:C(string z = "0"){c = z;cout << "C()" << endl;}string c; };class A { public:A(string x = " "){a = x;cout << "A()" << endl;}string a; };class B:public A { public:B(string x , string y, string z):A(x),c(z){b = y;cout << "B()" << endl;}C c;string b; };int main() {B b("b1","b2","b3");B bb("bb1","bb2","bb3");bb = b;cout << "bb.a:" << bb.a << endl;cout << "bb.b:" << bb.b << endl;cout << "bb.c.c:" << bb.c.c << endl;return 0; }運行結果:
子類和內嵌子對象都使用默認的時候,系統會調用子類和內嵌子對象的系統默認賦值運算符重載函數。
子類使用系統默認提供的賦值運算符重載,內嵌子對象類自實現賦值運算符重載函數。
#include <iostream> using namespace std;class C { public:C(string z = "0"){c = z;cout << "C()" << endl;}C & operator=(const C & another){if (this == &another) //判斷是否是自賦值return *this;this->c = another.c;cout << "C & operator=(const C & another)" << endl;return *this;}string c; };class A { public:A(string x = " "){a = x;cout << "A()" << endl;}string a; };class B:public A { public:B(string x , string y, string z):A(x),c(z){b = y;cout << "B()" << endl;}C c;string b; };int main() {B b("b1","b2","b3");B bb("bb1","bb2","bb3");bb = b;cout << "bb.a:" << bb.a << endl;cout << "bb.b:" << bb.b << endl;cout << "bb.c.c:" << bb.c.c << endl;return 0; }運行結果:
這個時候默認調用內嵌子對象的賦值運算符重載函數,然后默認調用子類系統默認提供的賦值運算符重載函數。
子類是自實現賦值運算符重載函數,內嵌子對象使用系統默認提供的賦值運算符重載。
#include <iostream> using namespace std;class C { public:C(string z = "0"){c = z;cout << "C()" << endl;}string c; };class A { public:A(string x = " "){a = x;cout << "A()" << endl;}string a; };class B:public A { public:B(string x , string y, string z):A(x),c(z){b = y;cout << "B()" << endl;}B & operator=(const B & another){if (this == &another) //判斷是否是自賦值return *this;cout << "B & operator=(const B & another)" << endl;A::operator=(another); //繼承賦值運算符重載函數this->b = another.b;return *this;}C c;string b; };int main() {B b("b1","b2","b3");B bb("bb1","bb2","bb3");bb = b;cout << "bb.a:" << bb.a << endl;cout << "bb.b:" << bb.b << endl;cout << "bb.c.c:" << bb.c.c << endl;return 0; }運行結果:
子類會調用自實現賦值運算符重載函數,內嵌子對象類不會調用系統默認提供的賦值運算符重載函數。
子類和內嵌子對象類都自實現賦值運算符重載函數。
#include <iostream> using namespace std;class C { public:C(string z = "0"){c = z;cout << "C()" << endl;}C& operator=(const C& another){if (this == &another) //判斷是否是自賦值return *this;this->c = another.c;cout << "C & operator=(const A & another)" << endl;return *(this);}string c; };class A { public:A(string x = " "){a = x;cout << "A()" << endl;}string a; };class B:public A { public:B(string x , string y, string z):A(x),c(z){b = y;cout << "B()" << endl;}B & operator=(const B& another){if (this == &another) //判斷是否是自賦值return *this;cout << "B & operator=(const B & another)" << endl;A::operator=(another); //繼承賦值運算符重載函數this->b = another.b;return *this;}C c;string b; };int main() {B b("b1","b2","b3");B bb("bb1","bb2","bb3");bb = b;cout << "bb.a:" << bb.a << endl;cout << "bb.b:" << bb.b << endl;cout << "bb.c.c:" << bb.c.c << endl;return 0; }運行結果:
當子類和內嵌子對象類都自實現賦值運算符重載函數的時候,不會調用內嵌子對象類的賦值運算符重載函數。
內嵌子對象顯式調用
#include <iostream> using namespace std;class C { public:C(string z = "0"){c = z;cout << "C()" << endl;}C & operator=(const C & another){if (this == &another) //判斷是否是自賦值return *this;this->c = another.c;cout << "C & operator=(const C & another)" << endl;return *this;}string c; };class A { public:A(string x = " "){a = x;cout << "A()" << endl;}A& operator=(const A& another){if (this == &another) //判斷是否是自賦值return *this;this->a = another.a;cout << "A & operator=(const A & another)" << endl;return *this;}string a; };class B:public A { public:B(string x , string y, string z):A(x),c(z){b = y;cout << "B()" << endl;}B & operator=(const B & another){if (this == &another) //判斷是否是自賦值return *this;cout << "B & operator=(const B & another)" << endl;A::operator=(another); //繼承父類賦值運算符重載函數c = another.c; //繼承內嵌類賦值運算符重載函數this->b = another.b;return *this;}C c;string b; };int main() {B b("b1","b2","b3");B bb("bb1","bb2","bb3");bb = b;cout << "bb.a:" << bb.a << endl;cout << "bb.b:" << bb.b << endl;cout << "bb.c.c:" << bb.c.c << endl;return 0; }運行結果:
實戰操作
實戰:使用系統默認的賦值運算符重載函數實現派生類的淺賦值。
代碼演示:
#include <iostream> using namespace std;class Student { public:Student(string name, int num, char sex):_name(name), _num(num), _sex(sex) {}Student(const Student& another){_name = another._name;_num = another._num;_sex = another._sex;}void dump(){cout << "name:" << _name << endl;cout << "num :" << _num << endl;cout << "sex :" << _sex << endl;} private:string _name;int _num;char _sex; };class Birthday { public:Birthday(int y, int m, int d):_year(y), _month(m), _day(d){}Birthday(const Birthday& b){_year = b._year;_month = b._month;_day = b._month;}void disBirthday(){cout << "birth date:" << _year << ":" << _month << ":" << _day << endl;} private:int _year;int _month;int _day; };class Graduate :public Student { public:Graduate(string name, int num, char sex, float salary, int y, int m, int d):Student(name, num, sex), _salary(salary), birth(y, m, d){_salary = salary;}Graduate(const Graduate & another):Student(another), birth(another.birth){_salary = another._salary;}void dis(){dump();cout << "salary:" << _salary << endl;birth.disBirthday();} private:float _salary;Birthday birth; };int main() {Graduate g("sun", 2001, 's', 10000, 1990, 9, 19);g.dis();Graduate gg("wang", 2002, 'c', 20000, 3990, 39, 39);g = gg;g.dis();return 0; }運行結果:
實戰:自實現顯式調用賦值運算符重載函數實現派生類的淺賦值。
代碼演示:
#include <iostream> using namespace std;class Student { public:Student(string name, int num, char sex):_name(name), _num(num), _sex(sex){}Student(const Student & another){_name = another._name;_num = another._num;_sex = another._sex;}Student & operator=(const Student & another){if (this == &another)return *this;this->_name = another._name;this->_num = another._num;this->_sex = another._sex;return *this;}void dump(){cout << "name:" << _name << endl;cout << "num :" << _num << endl;cout << "sex :" << _sex << endl;} private:string _name;int _num;char _sex; };class Birthday { public:Birthday(int y, int m, int d):_year(y), _month(m), _day(d){}Birthday(const Birthday & b){_year = b._year;_month = b._month;_day = b._month;}Birthday & operator=(const Birthday & another){if (this == &another)return *this;this->_year = another._year;this->_month = another._month;this->_day = another._month;return *this;}void disBirthday(){cout << "birth date:" << _year << ":" << _month << ":" << _day << endl;} private:int _year;int _month;int _day; }; class Graduate :public Student { public:Graduate(string name, int num, char sex, float salary, int y, int m, int d):Student(name, num, sex), _salary(salary), birth(y, m, d){_salary = salary;}Graduate(const Graduate& another):Student(another), birth(another.birth){_salary = another._salary;}Graduate & operator=(Graduate & another){if (this == &another)return *this;Student::operator =(another);birth = another.birth;this->_salary = another._salary;return *this;}void dis(){dump();cout << "salary:" << _salary << endl;birth.disBirthday();} private:float _salary;Birthday birth; };int main() {Graduate g("sun", 2001, 's', 10000, 1990, 9, 19);g.dis();Graduate gg("wang", 2002, 'c', 20000, 3990, 39, 39);g = gg;g.dis();return 0; }運行結果:
實戰:自實現顯式調用賦值運算符重載函數實現派生類的深賦值。
代碼演示:
#define _CRT_SECURE_NO_WARNINGS #include <iostream>using namespace std;class Student { public:Student(string name, int num, char sex):_name(name), _num(num), _sex(sex){strS = new char[13]{ "helloworld_S" };}Student(const Student& another){_name = another._name;_num = another._num;_sex = another._sex;}Student& operator=(const Student& another){if (this == &another)return *this;this->_name = another._name;this->_num = another._num;this->_sex = another._sex;delete[] strS;this->strS = new char[strlen(another.strS) + 1];strcpy(this->strS,another.strS);return *this;}void dump(){cout << "name:" << _name << endl;cout << "num :" << _num << endl;cout << "sex :" << _sex << endl;cout << "strS :" << strS << endl;} private:string _name;int _num;char _sex;char* strS; };class Birthday { public:Birthday(int y, int m, int d):_year(y), _month(m), _day(d){strB = new char[13]{ "helloworld_B" };}Birthday(const Birthday& b){_year = b._year;_month = b._month;_day = b._month;}Birthday& operator=(const Birthday& another){if (this == &another)return *this;this->_year = another._year;this->_month = another._month;this->_day = another._month;delete[] this->strB;this->strB = new char[strlen(another.strB) + 1];strcpy(this->strB, another.strB);return *this;}void disBirthday(){cout << "birth date:" << _year<< ":" << _month << ":" << _day << endl;cout << "strB :" << strB << endl;} private:int _year;int _month;int _day;char* strB; };class Graduate :public Student { public:Graduate(string name, int num, char sex, float salary, int y, int m, int d):Student(name, num, sex), _salary(salary), birth(y, m, d){_salary = salary;strG = new char[15]{ "helloworld_G" };}Graduate(const Graduate& another):Student(another), birth(another.birth){_salary = another._salary;}Graduate& operator=(Graduate& another){if (this == &another)return *this;Student::operator =(another);birth = another.birth;this->_salary = another._salary;delete[] strG;strG = new char[strlen(another.strG) + 1];strcpy(this->strG, another.strG);return *this;}void dis(){dump();cout << "salary:" << _salary << endl;cout << "strG :" << strG << endl;birth.disBirthday();} private:float _salary;Birthday birth;char* strG; };int main() {Graduate g("sun", 2001, 's', 10000, 1990, 9, 19);g.dis();cout << "\n**********************************\n" << endl;Graduate gg("wang", 2002, 'c', 20000, 3990, 39, 39);g = gg;g.dis();return 0; }運行結果:
總結
以上是生活随笔為你收集整理的派生类的赋值运算符重载【C++继承】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++赋值运算符重载【C++赋值运算符重
- 下一篇: 派生类的友元与析构【C++继承】