1. 程式人生 > >c++primer,自定義一個復數類

c++primer,自定義一個復數類

opera 指針 隨著 per call 拷貝構造函數 會銷 局部變量 eal

 1 #include<iostream>
 2 #include<string>
 3 #include<vector>
 4 #include<algorithm>
 5 #include<cstdio>
 6 #include<complex>
 7 using namespace std;
 8 
 9 class Complex{
10     //復數為直角坐標形式,a+bj
11 private:
12     double real;
13     double image;
14 public:
15     Complex() :real(0
), image(0){};// default constructor,初始化為0 16 Complex(double real, double image){ this->real = real; this->image = image; }//提供來了Complex c(0,1)的初始形式 17 Complex(const Complex& rhs){ (*this).real = rhs.real; image = rhs.image; } 18 ~Complex(){ /*cout << "deconstructor called\n";*/ }
19 double getReal()const{ return real; } 20 double getImage()const{ return image; } 21 22 //operator overload 23 Complex operator + (const Complex&rhs) //不能返回局部變量的引用,因為返回的是變量本身,變量隨著函數結束會銷毀掉 24 { 25 Complex result; 26 result.real= real + rhs.real; 27 result.image = image + rhs.image;
28 return result; 29 } 30 Complex operator-(const Complex&rhs) //註釋掉的代碼有錯誤,b-a得到一個表達式值,但b和a的值本身是沒變的 31 { 32 /*real = real - rhs.real; 33 image = image - rhs.image; 34 return *this;*/ 35 Complex result; 36 result.real = real - rhs.real; 37 result.image = image - rhs.image; 38 return result; 39 } 40 Complex&operator=(const Complex&rhs) 41 { 42 cout << "= called\n"; 43 //簡化版本 44 real = rhs.real; 45 image = rhs.image; 46 return *this; 47 } 48 /*ostream& operator<< (ostream&os)// 調用形式不符合平時輸出習慣 49 { 50 if (image<0) 51 os << real << image << "j" ; 52 else os << real << "+" << image << "j"; 53 return os; 54 }*/ 55 friend ostream& operator<<(ostream&os ,const Complex &lhs); 56 }; 57 ostream& operator<<(ostream&os, const Complex &lhs) 58 { 59 if (lhs.image < 0) os << lhs.real << lhs.image << "j"; 60 else os << lhs.real << "+" << lhs.image << "j"; 61 return os; 62 } 63 int main() 64 { 65 Complex a; //申請的內存分配在棧上 66 /*a << cout<<endl;*/ 67 Complex b(2, 4); 68 /*b << cout << endl;*/ 69 Complex c(b); 70 71 Complex d = b+c;//=是初始化,調用拷貝構造函數,而不是重載運算符= 72 /*d << cout << endl;*/ 73 Complex e(3, -3); 74 /*e << cout << endl; 75 b << cout << endl;*/ 76 a = b + e; 77 a = b - e; 78 /*a << cout << endl;*/ 79 Complex f = { 1, 2 }; 80 cout << a << "\n" << b << "\n" << c << endl; 81 cout << d << "\n" << e<<"\n" << f << endl; 82 vector<Complex> cv(10); 83 cv.push_back(f); 84 for (auto x:cv) 85 { 86 cout << x << endl; 87 } 88 89 }

一些問題:

假設自定義了一個Complex類

Q:為什麽需要自定義默認構造函數?

A:相比需要顯示提供參數的constructor,前者不需要用戶提供初始值,如Complex s,如果要用vector容納Complex對象,要求Complex有自定義的默認構造函數,如下用法才能work:

Vector<Complex> cv(n),n個默認初始化的復數對象。

Q:定義單參構造函數有什麽問題?

A:單參構造函數是一個隱式轉換函數,如Complex c=7,會把右邊的int轉換為一個復數對象,加上explicit修飾該函數,能禁止這種隱式轉換,只能使用直接初始化形式:Complex c(7)

Q:copy constructor的參數必須是引用,編譯器禁止使用類型參數

A:如果是類型參數,Complex(Complex arg),參數傳遞時會構造實參的一個副本,循環調用拷貝構造函數,如果參數是引用,Complex(Complex&arg),使用的是實參本身,而且必須要加上const,因為non-const引用不接受const引用類型的實參。

Q:Complex的析構函數,deconstructor的函數體寫法?

A:復數有兩個private成員,都是double,析構時需要做什麽工作?如果成員變量有指針,可以把指針置為空。

Q:重載輸出運算符,只能overload為該類的友元函數?

A:如果是成員函數,ostream& operator<<(ostream& os),使用時的形式為c.operator<<cout<<endl或c<<cout<<endl;如果是非成員函數,要訪問私有變量,需要在類內聲明為友元:friend ostream& operator<<(ostream& os,const Complex&rhs ),調用形式為:cout<<c<<endl;

Q:重載賦值運算符與拷貝初始化的區別?

A:Complex a=c;這調用了copy ctr,而不是assingn operator,a=c+c,調用了重載的operator+和operator=,編譯器如何區分調用哪一種函數?

c++primer,自定義一個復數類