实现复数类的基本成员函数,复数之间比较大小以及复数的四则运算。

设z1 = a + bi,z2 = c + di(a、b、c、d∈R)是任意两个复数,

复数乘法:

    (a + bi)(c + di) = (ac - bd) + (bc + ad)i。

复数除法:

    (a + bi) / (c + di) = (ac + bd) / (c ^ 2 + d ^ 2) + (bc - ad) / (c ^ 2 + d ^ 2)i。

代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

class Complex
{
public:
	void Display()
	{
		cout << "_real:" << _real << "      "<<"_p_w_picpath:" << _p_w_picpath << endl;
	}
public:
	//Complex()//无参数构造函数
	//{
	//	_real=_real;
	//	_p_w_picpath=_p_w_picpath;
	//}
	Complex(double real = 1.0, double p_w_picpath = 2.0)//全缺省参数构造函数
	{
		//cout << "Complex(double real = 1.0, double p_w_picpath = 2.0)" << endl;
		_real = real;
		_p_w_picpath = p_w_picpath;
	}
	//Complex(const Complex& c)//拷贝构造函数。注意引用符,若为值传递则可能会引发无穷递归
	//{
	//	_real = c._real;
	//	_p_w_picpath = c._p_w_picpath;
	//}
	Complex(const Complex& c)拷贝构造函数
		:_real(c._real)
		,_p_w_picpath(c._p_w_picpath)
	{
		cout << "Complex(const Complex& c)" << endl;
	}
	~Complex()//析构函数
	{
		//cout << "~Complex()"<< endl;
	}
public:
	Complex& operator=(const Complex& x)//赋值操作符的重载
	{
		if (this != &x)
		{
			this->_real = x._real;
			this->_p_w_picpath = x._p_w_picpath;
		}
		return *this;
	}
	bool operator==(const Complex& x)//比较两个复数是否相等
	{
		return this->_real == x._real && this->_p_w_picpath == x._p_w_picpath;
	}
	bool operator>(const Complex& x)//判断第一个复数大于第二个复数,分为多种情况
	{
		if (this->_real && x._real)
		{
			if (this->_real > x._real)
				return true;
			if (this->_real == x._real && this->_p_w_picpath > x._p_w_picpath)
				return true;
		}
		else if (this->_real)
			return true;
		else if (!this->_real || !x._real)
		{
			if (this->_p_w_picpath > x._p_w_picpath)
				return true;
		}
		else
			return false;
		return false;
	}
	bool operator<(const Complex& x)//判断第一个复数小于第二个复数,分为多种情况
	{
		if (this->_real && x._real)
		{
			if (this->_real < x._real)
				return true;
			if (this->_real == x._real && this->_p_w_picpath < x._p_w_picpath)
				return true;
		}
		else if (x._real)
			return true;
		else if (!this->_real || !x._real)
		{
			if (this->_p_w_picpath < x._p_w_picpath)
				return true;
		}
		else
			return false;
		return false;
	}
	Complex operator + (const Complex& x)//加法。+匿名对象不用&返回
	{
		Complex tmp;
		tmp._real = this->_real + x._real;
		tmp._p_w_picpath = this->_p_w_picpath + x._p_w_picpath;
		return tmp;
	}
	Complex& operator += (const Complex& x)//+=匿名对象用&返回this
	{
		this->_real += x._real;
		this->_p_w_picpath += x._p_w_picpath;
		return *this;
	}
	Complex operator - (const Complex& x)//减法
	{
		Complex tmp;
		tmp._real = this->_real - x._real;
		tmp._p_w_picpath = this->_p_w_picpath - x._p_w_picpath;
		return tmp;
	}
	Complex& operator -= (const Complex& x)
	{
		this->_real -= x._real;
		this->_p_w_picpath -= x._p_w_picpath;
		return *this;
	}
	Complex operator * (const Complex& x)//乘法
	{//复数乘法运算:(a + bi)*(c + di) = (ac - bd) + (ad + bc)i;
		Complex tmp; 
		tmp._real = this->_real * x._real - this->_p_w_picpath * x._p_w_picpath;
		tmp._p_w_picpath = this->_real * x._p_w_picpath + this->_p_w_picpath * x._real;
		return tmp;
	}
	Complex& operator *= (const Complex& x)
	{
		*this = *this * x;
		return *this;
	}
	Complex operator / (const Complex& x)//除法
	{//复数除法运算:(a+bi)/(c+di) = x+yi, x =(ac+bd)/(c*c+d*d), y =(bc-ad)/(c*c+d*d);
		Complex tmp;
		tmp._real = (this->_real * x._real + this->_p_w_picpath * x._p_w_picpath)
			        / (x._real*x._real + x._p_w_picpath*x._p_w_picpath);
		tmp._p_w_picpath = (this->_p_w_picpath * x._real - this->_real * x._p_w_picpath)
			        / (x._real*x._real + x._p_w_picpath*x._p_w_picpath);
		return tmp;
	}
	Complex& operator /= (const Complex& x)
	{
		*this = *this / x;
		return *this;
	}
private:
	double _real;
	double _p_w_picpath;
};

void Test()
{
	//构造函数
	//Complex p; 
	//p.Display();
	Complex p1;
	Complex p2(2.0,1.0);
	p1.Display();
	p2.Display();
	//拷贝构造函数
	Complex p3(p1);
	Complex p4 = p1;
	p3.Display();
	p4.Display();
}

void Test1()
{//操作符的重载
	Complex p1(2.0, 3.0);
	Complex p2(2.0, 1.0);
	Complex p;
	p1.Display();
	p2.Display();
	p = p1;
	p.Display();
	bool ret;
	ret = p1 == p2;
	cout << "---------ret = " << ret << endl;
	ret = p1 > p2;
	cout << "---------ret = " << ret << endl;
	ret = p1 < p2;
	cout << "---------ret = " << ret << endl;
}

void Test2()
{//复数类的四则运算
	Complex p1(1.0, 2.0);
	Complex p2(2.0, 1.0);
	Complex p3(3.0, 5.0);
	Complex p4(2.0, 3.0);
	Complex p5(4.0, 8.0);
    p1.Display();
	//加法
	p2.Display();
	Complex add1 = p2 + p1;
	cout << "--------------------add1" << endl;
	add1.Display();
	p2 += p1;
	cout << "--------------------add2" << endl;
	p2.Display();
	cout << endl << endl;
	Complex sub1 = p3 - p1;
	//减法
	p3.Display();
	cout << "--------------------sub1" << endl;
	sub1.Display();
	p3 -= p1;
	cout << "--------------------sub2" << endl;
	p3.Display();
	cout << endl << endl;
	//乘法
	p4.Display();
	p4 *= p1;
	cout << "--------------------mul" << endl;
	p4.Display();
	cout << endl << endl;
	//除法
	p5.Display();
	p5 -= p2;
	cout << "--------------------div" << endl;
	p5.Display();
}

int main()
{
	Test();
	Test1();
	Test2();
	system("pause");
	return 0;
}

简述构造函数、拷贝构造函数和析构函数。

一. 构造函数
1. 构造函数是一种用于创建对象的特殊成员函数,当创建对象时,系统自动调用构造函数。
2. 构造函数名与类名相同,一个类可以拥有多个构造函数(重载),构造函数可以有任意类型的参数,但不能具有返回类型,连Void也不可以,它有隐含的返回值,该值由系统内部使用。
3. 构造函数的作用是:为对象分配空间;对数据成员赋初值;请求其他资源。
4. 如果一个类没有定义构造函数,编译器会自动生成一个无参的默认构造函数。

二. 拷贝构造函数:
1. 当构造函数的参数为自身类的引用时,这个构造函数称为拷贝构造函数。拷贝构造函数的功能是用一个已有对象初始化一个正在建立的同类对象。
2. 拷贝构造函数的特点如下:
(1)该函数名与类同名,因为它也是一种构造函数,并且该函数也不被指定返回类型;
(2)该函数只有一个参数,并且是对某个对象的引用;
(3)每个类都必须有一个拷贝构造函数;
(4)如果程序员没有显式地定义一个拷贝构造函数,那么,C++编译器会自动生成一个缺省的拷贝构造函数.
(5)拷贝构造函数的目的是建立一个新的对象实体,所以,一定要保有证新创建的对象有着独立的内存空间,而不是与先前的对象共用。
     在定义一些类时,有时需要(而且强立推荐)显式地定义拷贝构造函数。
3.拷贝构造函数主要在如下三种情况中起初始化作用。
(1)声明语句中用一个对象初始化另一个对象(一定是在"声明并初始化对象"时被调用);例如TPoint P2(P1)表示由对象P1初始化P2时,需要调用拷贝构造函数。
(2)将一个对象作为参数按值调用方式(而不是指针)传递给另一个对象时生成对象副本(即 复制构造函数在"对象作为函数参数"时被调用)。当对象作为函数实参传递给函数形参时,如p=f(N),在调用f()函数时,对象N是实参,要用它来初始化被调用函数的形参,这时需要调用拷贝构造函数。
(3)生成一个临时的对象作为函数的返回结果。但对象作为函数返回值时,如return R时,系统将用对象R来初始化一个匿名对象,这时需要调用拷贝构造函数。
4.拷贝构造函数的执行:
(1)用已有对象初始化创建对象。 
(2)当对象作函数参数时,因为要用实参初始化形参,也要调用拷贝构造函数。
(3)函数返回值为类类型时,情况也类似。

三. 析构函数:
1. 析构函数名字为符号“~”加类名,析构函数没有参数和返回值。
2. 一个类中只可能定义一个析构函数,所以析构函数不能重载。
3. 析构函数的作用是进行清除对象,释放内存等。当对象超出其定义范围时(即释放该对象时),编译器自动调用析构函数。
   在以下情况下,析构函数也会被自动调用:
   (1)如果一个对象被定义在一个函数体内,则当这个函数结束时,该对象的析构函数被自动调用。
   (2)若一个对象是使用new运算符动态创建的,在使用delete运算符释放它时,delete将会自动调用析构函数。用new创建的对象,必须用delete销毁。
4. delete释放new产生的空间,而delete [] 释放new []产生的数组空间。