c++primer,自定义一个复数类

 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=,编译器如何区分调用哪一种函数?

时间: 2024-11-08 20:37:36

c++primer,自定义一个复数类的相关文章

【c++】实现一个复数类

// 实现一个复数类(complex) //要求:1:实现不带参 / 带参数 /带默认参数的几种构造函数. // 2:实现拷贝构造 / 析构函数. #include <iostream> using namespace std; // 带参数的构造函数 class complex { private: double _real; double _image; public: void print(); complex(double _r, double _i); ~complex(); };

C++ 声明并实现一个复数类

<pre name="code" class="cpp">/****************************************************************************************** complex.hpp: Copyright (c) Bit Software, Inc.(2013), All rights reserved. Purpose: 声明并实现一个复数类 难度:** Author:

如何自定义一个异常类

如何自己定义一个异常类来管理相应的异常? 1) 为这个找一个近似的类作为父类. 2) 在该类中编写两个构造器: a) 默认构造器; b) 带String message参数的构造器且在该构造器中使用 super(message); 语句     来调用父类的构造器完成异常原因的更改. 以下实例为,创建一个小猫对象,其年龄为负数则显示为异常 public class Exception7 { public static void main(String[] args) { Cat c1=null;

自定义一个异常类模板代码实例

一:自定义异常类: package 自定义异常; //或者继承RuntimeException(运行时异常) public class MyException extends Exception { private static final long serialVersionUID = 1L; // 提供无参数的构造方法 public MyException() { } // 提供一个有参数的构造方法 public MyException(String message) { super(mes

第十一篇 自定义一个缓存类(甚用~)

1 //自定义缓存类 2 public class CacheHelper<T> where T:class 3 { 4 private class Entity 5 { 6 public T Value{get;set;} 7 public DateTime Expiretime { get; set; } 8 } 9 private static readonly Dictionary<string, Entity> Dic=new Dictionary<string,E

Python自定义一个数组类,支持数组之间的四则运算和其他常见方法

class MyArray: '''保证输入的内容是整型.浮点型''' def ___isNumber(self, num): if not isinstance(num, (int,float)): return False return True #开始写构造函数,接受可变长度的数组 def __init__(self, *args): if args == None: self.__value = [] else: for a in args: if not self.___isNumbe

自定义一个类加载器

http://www.cnblogs.com/xrq730/p/4847337.html 为什么要自定义类加载器 类加载机制:http://www.cnblogs.com/xrq730/p/4844915.html 类加载器:http://www.cnblogs.com/xrq730/p/4845144.html 这两篇文章已经详细讲解了类加载机制和类加载器,还剩最后一个问题没有讲解,就是 自定义类加载器.为什么我们要自定义类加载器?因为虽然Java中给用户提供了很多类加载器,但是和实际使用比起

Android自定义一个属于自己的时间钟表

1.概述 本文主要讲解的是如何自定义一个时间钟表,通过简单的练习可以简单学习android当中自定义view的一些常用绘图技巧,优化android绘图操作.言归正传,首先看下我们需要实现的效果: 当我们看到这个效果的时候脑子里应该有一定的思路了,我们应该把它分解成以下几个步骤: 1.仪表盘(圆) 2.刻度线(长 中 短) 3.刻度值(1-12) 4.指针(时  分  秒) 5.移动指针,计算指针位置 现在我们已经很清楚自己的思路了,那么我们一个一个来. 第一步:1.自定义View的属性,首先在r

C++习题 复数类--重载运算符+,-,*,/

Description 定义一个复数类Complex,重载运算符"+","-","*","/",使之能用于复数的加.减.乘.除.运算符重载函数作为Complex类的成员函数.编写程序,分别求两个复数之和.差.积和商. Input 两个复数 Output 两个复数之和.差.积和商 Sample Input 3 4 5 -10 Sample Output c1+c2=(8.00,-6.00i) c1-c2=(-2.00,14.00