01 C++中complex.h头文件的写法

1. 引言

本系列内容主要是介绍C++的学习笔记。第一部分01介绍不包含指针的头文件complex.h的写法以及使用,即用C++编写一个数学中复数的头文件,运用类构造、函数构造、运算符重载等实现在对复数的数学计算。

2. complex.h头文件的编写

1)头文件使用防卫式声明结构

#ifndef __COMPLEX__
#define  __COMPLEX__

//该部分为复数类结构定义内容

#endif //__COMPLEX__
说明:若有多个程序使用到头文件时会更加方便,通过头文件ifndef判断,编译器不会出现重复编译;

2)定义头文件中复数类complex的结构

#ifndef __COMPLEX__
#define __COMPLEX__

class complex;
complex&
__doapl(complex * ths, const complex& r);
complex&
__doami(complex * ths, const complex& r);
complex&
__doaml(complex * ths, const complex& r);
complex&
__doadv(complex * ths, const complex& r);

class complex
{
public:
	complex(double r = 0, double i = 0) :re(r), im(i){ }; //构造函数
	complex& operator += (const complex&);
	complex& operator -= (const complex&);
	complex& operator *= (const complex&);
	complex& operator /= (const complex&);
	//complex operator - (const complex&);

	double real() const { return re; }
	double imag() const { return im; }

private:
	double re, im;

	friend complex& __doapl(complex *, const complex&);
	friend complex& __doami(complex *, const complex&);
	friend complex& __doaml(complex *, const complex&);
	friend complex& __doadv(complex *, const complex&);
};
注意点:

a. 构造函数

对复数中实部和虚部的赋初值采用冒号后面赋值结构;

b. 传参类型和返回值类型

对于函数中的参数传递和返回值传递能用引用类型尽量传引用(通常传引用内存所占的字节较小,速度快),即C++中在参数后面加和字符&;

C++中详细引用的用法,我查找了网上相关资料,如http://www.cnblogs.com/Mr-xu/archive/2012/08/07/2626973.html;

因传引用后,传的是地址,所以被传对方若修改内容则原对象也会改变。因此,若传入的参数不会改变,则在函数传递参数前加const来防止修改自己(修改后编译器会报错);

c. 成员函数和非成员函数

成员函数中有隐藏的this,而成员函数中没有。也就是说在使用成员函数中可以通过this的传入来表示这个传入的类;

任何操作都可以有两种写法,不一定是谁好谁坏。而<< 操作符,只能是非成员函数的写法。

d. 操作符重载

C++中操作符(operator +=)就是函数,可以重新设定;

在复数类complex中通过成员函数实现+=,-=等操作符对复数的操作,+=操作符包括+=右边和左边两部分操作数据,传入参数显示的只是右边复数常引用,实际上此时还包含左边传入复数的本身。

e. 内联函数

在复数类内实现的函数如real() 、imag()函数默认是内联函数,处理速度快(但函数实际是不是内联要看编译器的情况,一般函数复杂,编译器就不会识别为内联)。

f. 友元的作用

在类结构中函数使用friend关键字即友元,在使用时,友元对象可以自由取得类中private成员;

记住相同class的各个objects互为友元。

3)实现部分对复数运算符的操作

inline double
real(const complex& x)
{//1取实部
	return x.real();
}

inline complex&
__doapl(complex * ths, const complex& r)
{//2实现运算符+=操作
	ths->re += r.re;
	ths->im += r.im;
	return *ths;
}

inline complex&
complex::operator += (const complex& r)
{//3运算符+=操作
	return __doapl(this, r);
}

inline complex
operator + (const complex& x, const complex& y)
{//4实现运算符+操作
	return complex(real(x) + real(y), imag(x) + imag(y));
}

inline complex
conj(const complex& x)
{//5实现共轭复数操作
	return complex(real(x), -imag(x));
}

inline bool
operator == (double x, const complex& y)
{//6实现操作符==操作
	return x == real(y) && 0 == imag(y);
}

注意点:

a. 使用inline关键字

在类外部实现的成员函数和非成员函数前加inline,就是告诉编译器如果能实现inline就inline的方式,也就是内联函数;

b. 函数3运算符+=操作

函数3中就运用了关键字this,因为函数3是成员函数的实现。如对复数+=操作:c1 += c2,c1的地址传入就是表示this。最后通过函数2返回*ths来返回c1值本身,在整个过程中c1的存储位置不会变;

函数2之所以能以引用类型接收,一方面是*ths返回值是内存已经存在,不是local object创建的;令一方面虽然传递的是值类型而用引用接收,是因为传递者无需知道接收者是以引用形式接收。

c. 函数4实现运算符+操作

函数4的返回类型是complex,而不是引用。此时,也只能是complex类型。因为,实现+是在内存中重新创建一个complex对象(即local object),返回引用后原创建对象会失效。

3. 在主程序中实现对头文件的操作
// complex_cPP.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 
#include "complex.h"
using namespace std;

ostream&
operator << (ostream& os, const complex& x)
{
	return os << "(" << real(x) << "," << imag(x) << ")";
}

int _tmain(int argc, _TCHAR* argv[])
{
	complex c1(4, 1);
	complex c2(4, 1);
	complex c3(2, 3);
	complex c4(4, 1);
	complex c5(2, 3);
	complex c6(4, 1);
	complex c7(2, 3);
	complex c8(4, 1);
	complex * c0 = new complex(2, 1);
	
	cout << 12 << endl;
	cout << "c0= " << *c0 << endl;
	cout << "c1 = " << c1 << endl;
	cout << "c2 = " << c2 << endl;
	cout << "c3 = " << c3 << endl;
	cout << "c4 = " << c4 << endl;
	cout << "c5 = " << c5 << endl;
	cout << "c6 = " << c6 << endl;
	cout << "c7 = " << c7 << endl;
	cout << "c8 = " << c8 << endl;

	//cout << "c1 += c2 => " << (c1 += c2) << endl;
	//cout << "c3 -= c4 => " << (c3 -= c4) << endl;
	//cout << "c5 *= c6 => " << (c5 *= c6) << endl;
	//cout << "c7 /= c8 => " << (c7 /= c8) << endl;

	//cout << c1 + c2 << endl;
	//cout << c1 + 5.0 << endl;
	//cout << 6.0 + c1 << endl;

	//cout << "c1 - c2 = " << (c1 - c2) << endl;
	//cout << "5 - c1 = " << (5 - c1) << endl;
	//cout << "c1 - 5 = " << (c1 - 5) << endl;

	//cout << "c1 * c2 = " << (c1 * c2) << endl;
	//cout << "5 * c1 = " << (5 * c1) << endl;
	//cout << "c1 * 5 = " << (c1 * 5) << endl;

	//cout << "c1 / c2 = " << (c1 / c2) << endl;
	//cout << " c1 / 5 = " << (c1 / 5) << endl;
	
	//cout << " -c1  = " << (-c1) << endl;
	//cout << " +c1  = " << (+c1) << endl;

	//cout << "conj(c1)" << conj(c1) << endl;
	//cout << "norm(c1)" << norm(c1) << endl;

	cout << "(c1 == c2) " << (c1 == c2) << endl;
	cout << "(c1 == 5) " << (c1 == 5) << endl;
	cout << "(6 == c1) " << (6 == c1) << endl;

	cout << "(c3 != c4) " << (c3 != c4) << endl;
	cout << "(c3 != 5) " << (c3 != 5) << endl;
	cout << "(6 != c3) " << (6 != c3) << endl;
	return 0;
}

注意点:

a. 文件开头引用头文件#include "complex.h"

a. 实现<<操作符,能将复数以自己的方式打印输出。



说明:本篇代码内容原文件放在下面百度云盘共享下http://pan.baidu.com/s/1kUNmj6B,使用编译器VS2013。


你可能感兴趣的:(02,C++)