C++面向对象程序设计的一些知识点(5)
生活随笔
收集整理的這篇文章主要介紹了
C++面向对象程序设计的一些知识点(5)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
摘要:運算符能給程序員提供一種書寫數學公式的感覺,本質上運算符也是一種函數,因此有類內部運算符和全局運算符之分,通過重載,運算符的“動作”更加有針對性,編寫代碼更像寫英文文章。
1、C++標準允許將運算符重載為類成員或者全局的,一般如果是全局的話,為了效率,都是把它們定義為類友元函數。
1 /* 2 ** 重載全局運算符“+”、“-”,代碼如下: 3 */ 4 #include <iostream> 5 6 using namespace std; 7 8 //class Complex; 9 //Complex operator+(const Complex &c1, const Complex &c2); 10 //Complex operator-(const Complex &c1, const Complex &c2); 11 // 我的疑問:聲明為全局的有什么好處的,或者說有什么必要的么? 12 class Complex 13 { 14 public: 15 Complex(double real = 0.0, double image = 0.0) 16 { 17 this->real = real; 18 this->image = image; 19 } 20 public: 21 void displayComplex() 22 { 23 if(image >= 0) 24 cout << "(" << real << '+' << image << 'i' << ")"; 25 else 26 cout << "(" << real << image << 'i' << ")"; 27 } 28 friend Complex operator+(const Complex &c1, const Complex &c2); 29 friend Complex operator-(const Complex &c1, const Complex &c2); 30 private: 31 double real; 32 double image; 33 }; 34 35 Complex operator+(const Complex &c1, const Complex &c2) 36 { 37 Complex complexTemp; 38 complexTemp.real = c1.real + c2.real; 39 complexTemp.image = c1.image + c2.image; 40 return complexTemp; 41 } 42 Complex operator-(const Complex &c1, const Complex &c2) 43 { 44 Complex complexTemp; 45 complexTemp.real = c1.real - c2.real; 46 complexTemp.image = c1.image - c2.image; 47 return complexTemp; 48 } 49 int main() 50 { 51 Complex c, c1(1.1, 2.2), c2(3.3, 4.4); 52 c = c1 + c2; 53 c = c1 - c2; // operator-(c1, c2); 54 c1.displayComplex(); 55 cout << "-"; 56 c2.displayComplex(); 57 cout << "="; 58 c.displayComplex(); 59 cout << endl; 60 61 int i; 62 cin >> i; 63 return 0; 64 } 重載為友元函數2、運算符重載的一些基本規則:
禁止用戶發明C++語言運算符之外的其他運算符
不要試圖改變重載運算符的語義,保持重載后的運算語義與內置運算符語義一致,否則會帶來思維上的混亂
不能重載.、.*、::、?:
不能重載#、##
不能重載sizeof()、typeid()
不能重載static_cast<>、dynamic_cast<>、const_cast<>、reinterpret_cast<>
3、運算符重載時,它的返回值類型會有程序運行效率和使用重載運算符方便程度的差別
當返回值為對象時,拷貝構造函數會構建一個臨時對象
當返回值為對象引用時,不會引起構造函數的調用,其返回值可以作為左值
當返回值為對象指針時,不會引發構造函數的調用,其返回值可以作為左值
1 /* 2 ** 重載運算符,返回不同類型的差別 3 */ 4 #include <iostream> 5 6 using namespace std; 7 8 class Complex 9 { 10 public: 11 Complex(double real = 0.0, double image = 0.0) 12 { 13 this->real = real; 14 this->image = image; 15 } 16 Complex(const Complex &c) // 拷貝構造函數 17 { 18 real = c.real; 19 image = c.image; 20 cout << "copy constructing..." << endl; 21 } 22 public: 23 Complex operator+(const Complex &c) 24 { 25 Complex complexTemp; 26 complexTemp.real = real + c.real; 27 complexTemp.image = image + c.image; 28 return complexTemp; // 此時會調用拷貝構造函數,構造一個臨時對象 29 } 30 Complex& operator-(const Complex &c) 31 { 32 real -= c.real; 33 image -= c.image; 34 return *this; 35 } 36 void displayComplex() 37 { 38 if(image >= 0) 39 cout << "(" << real << "+" << image << "i" << ")"; 40 else 41 cout << "(" << real << image << "i" << ")"; 42 } 43 private: 44 double real; 45 double image; 46 }; 47 int main() 48 { 49 Complex c, c1(1.1, 2.2), c2(3.3, 4.4); 50 (c1 + c2).displayComplex(); 51 cout << "Before c1 - c2" << endl; 52 c1.displayComplex(); 53 cout << endl; 54 cout << "After c1 - c2" << endl; 55 (c1 - c2).displayComplex(); 56 cout << endl; 57 int i; 58 cin >> i; 59 return 0; 60 } 重載返回值不同類型的差別4、運算符重載示例:
賦值運算符
1 /* 2 ** 賦值運算符“=”重載 3 */ 4 #include <iostream> 5 #include <cstring> 6 7 using namespace std; 8 9 class Student 10 { 11 public: 12 Student(char *name = "") 13 { 14 pName = new char[strlen(name) + 1]; 15 strcpy(pName, name); 16 } 17 ~Student() 18 { 19 delete pName; 20 pName = NULL; 21 } 22 public: 23 Student &operator=(const Student &student) 24 { 25 cout << "assignment called..." << endl; 26 // 若為同一個對象則直接返回即可 27 if(this == &student) // 注意這里需要用指針比較,因為沒有實現對象比較的運算符呢 28 { 29 cout<< "\tExact the same object." << endl; 30 return *this; 31 } 32 delete pName; // 否則,先釋放資源 33 pName = new char[strlen(student.pName) + 1]; 34 strcpy(pName, student.pName); 35 return *this; 36 } 37 void show() 38 { 39 cout << pName << endl; 40 } 41 private: 42 char *pName; 43 }; 44 45 int main() 46 { 47 Student s1, s2("zhangsan"); 48 s1 = s1; 49 50 s1 = s2; 51 s1.show(); 52 53 int i; 54 cin >> i; 55 return 0; 56 } 賦值運算符重載示例函數符
1 /* 2 ** 函數符“()”重載 3 */ 4 #include <iostream> 5 6 using namespace std; 7 8 class Student 9 { 10 public: 11 Student(int chinese, int math, int english) 12 { 13 this->chinese = chinese; 14 this->math = math; 15 this->english = english; 16 } 17 ~Student() 18 { } 19 public: 20 void operator()(int index = 0) 21 { 22 switch(index) 23 { 24 case 0: 25 cout << "chinese:" << chinese << endl; 26 break; 27 case 1: 28 cout << "math:" << math << endl; 29 break; 30 case 2: 31 cout << "english:" << math << endl; 32 break; 33 default: 34 cout << "not found" << endl; 35 } 36 } 37 private: 38 int chinese; 39 int math; 40 int english; 41 }; 42 int main() 43 { 44 Student student(80, 90, 92); 45 student(); 46 student(0); 47 student(1); 48 student(2); 49 student(3); 50 student(4); 51 52 int i; 53 cin >> i; 54 return 0; 55 } 函數調用符重載示例下標運算
1 /* 2 ** 下表運算符“[]”重載 3 */ 4 #include <iostream> 5 6 using namespace std; 7 8 class UserString 9 { 10 public: 11 UserString(char *str) 12 { 13 len = strlen(str); 14 this->str = new char[len + 1]; 15 strcpy(this->str, str); 16 } 17 ~UserString() 18 { 19 delete str; 20 str = NULL; 21 } 22 public: 23 char operator[](int index) 24 { 25 if(index >= 0 && index < len) // 判斷越界 26 return str[index]; 27 else 28 { 29 cout << "beyond scope..." << endl; 30 return ' '; 31 } 32 } 33 int getLength() 34 { 35 return len; 36 } 37 private: 38 char *str; 39 int len; 40 }; 41 42 int main() 43 { 44 UserString us("zhangsan"); 45 cout << "\"zhangsan\" length:" << us.getLength() << endl; 46 int length = us.getLength(); 47 int i; 48 for(i = 0;i < length;i++) 49 cout << us[i]; // 使用[]訪問 50 cout << endl; 51 cout << us[i]; 52 53 cin >> i; 54 return 0; 55 } 下表運算符重載示例運算符++、--
1 /* 2 ** 運算符“++、--”重載 3 */ 4 #include <iostream> 5 6 using namespace std; 7 8 class Integer 9 { 10 public: 11 Integer(int data) 12 { 13 this->data = data; 14 } 15 Integer(const Integer &i) 16 { 17 this->data = i.data; 18 } 19 ~Integer() 20 { } 21 public: 22 Integer operator++(int) 23 { 24 Integer temp(*this); 25 data++; 26 return temp; 27 } 28 Integer operator++() 29 { 30 data++; 31 return *this; 32 } 33 void show() 34 { 35 cout << data << endl; 36 } 37 private: 38 int data; 39 }; 40 41 int main() 42 { 43 Integer x(1); 44 (x++).show(); 45 (++x).show(); 46 47 int i; 48 cin >> i; 49 return 0; 50 } ++、--運算符重載示例類型轉換
1 /* 2 ** 類型轉換運算符重載,從對象到內置類型 3 */ 4 #include <iostream> 5 6 using namespace std; 7 8 class Complex 9 { 10 public: 11 Complex(double real, double image) 12 { 13 this->real = real; 14 this->image = image; 15 } 16 public: 17 operator double() 18 { 19 return real; 20 } 21 private: 22 double real; 23 double image; 24 }; 25 26 int main() 27 { 28 double d = 1.1; 29 Complex c(4.0, 5.0); 30 31 d += c; // 此時c.operator double()返回4.0 32 cout << d << endl; 33 34 int i; 35 cin >> i; 36 return 0; 37 } 類型轉換-從對象到內置類型 1 /* 2 ** 類型轉換運算符重載,從內置類型到對象 3 */ 4 #include <iostream> 5 6 using namespace std; 7 8 class Complex 9 { 10 public: 11 Complex(double real, double image) 12 { 13 this->real = real; 14 this->image = image; 15 } 16 Complex(const Complex &c) 17 { 18 real = c.real; 19 image = c.image; 20 cout << "copy constructor called..." << endl; 21 } 22 Complex(double real) 23 { 24 this->real = real; 25 this->image = 0; 26 cout << "one parameter called..." << endl; 27 } 28 ~Complex() 29 {} 30 public: 31 Complex& operator+=(const Complex &c) 32 { 33 real += c.real; 34 image += c.image; 35 cout << "overload operator+= called..." << endl; 36 return *this; 37 } 38 void show() 39 { 40 cout << real; 41 if(image >= 0) 42 cout << "+" << image << "i" << endl; 43 else 44 cout << image << "i" << endl; 45 } 46 private: 47 double real; 48 double image; 49 }; 50 51 int main() 52 { 53 Complex c1(0, 1.1); 54 c1 += 3.3; 55 c1.show(); 56 57 int i; 58 cin >> i; 59 return 0; 60 } 類型轉換-從內置類型到對象5、運算符重載規則
| 運算符 | 規則 |
| 所有單目運算符 | 建議重載為非static成員函數 |
| =、()、[]、->、* | 建議重載為非static成員函數 |
| +=、-=、/=、*=、&=、|=、~=、%=、>>=、<<= | 建議重載為非static成員函數 |
| 所有其他運算符 | 建議重載為全局函數或類的友元函數 |
總結
以上是生活随笔為你收集整理的C++面向对象程序设计的一些知识点(5)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开启Windows8里面的Hyper-V
- 下一篇: Java JPanel的使用