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
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=,编译器如何区分调用哪一种函数?
原文链接: https://www.cnblogs.com/hchacha/p/7217404.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/257192
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!