使用类模板实现复数类
原创
©著作权归作者所有:来自51CTO博客作者zorch的原创作品,请联系作者获取转载授权,否则将追究法律责任
写在前面
最近正好有时间, 系统的学习一下C++中的面向对象思想, 实现一下基本的复数类, 主要参考了B站侯捷老师的C++课程(《C++面向对象高级编程(上)-基于对象&面向对象》), 有兴趣的小伙伴们可以去学习一下, 需要有一定的C++面向对象基础, 前面几节介绍了复数类的创建, 以及类的分文件编写时候需要注意的一些细节, 重点讲解了操作符重载这部分内容, 相当于是一个复习与巩固.
鉴于课程开始介绍过使用类模板创建一个复数类, 但是并没有完整实现, 下面我用之前学过的类模板的内容, 搞出来一个使用类模板创建的复数类.
代码
分文件编写, 头文件中包含类的声明与实现, 构造函数、成员函数的类外实现.
运行环境
MacOS 11.3
g++ -std=c++11
complex_by_template.h
// 防卫式声明
#ifndef __COMPLEX__
#define __COMPLEX__
// ----- 前置声明 -----
template<typename T>
class complex;
// 标准库函数: do assignment plus
template<typename T>
complex<T>& __doapl (complex<T> *ths, const complex<T>& r);
template<typename T>
inline complex<T>&
__doapl(complex<T>* ths, const complex<T>& r)
{
ths->re += r.re;
ths->im += r.im;
return *ths;
}
// ----- 类的声明 -----
// 采用模板
template<typename T>
class complex
{
public:
// 构造函数(函数名要与类名相同)
complex (T r=0,T i=0): re (r), im (i)
{ }
complex& operator += (const complex&);
T real () const {return re;}
T imag () const {return im;}
private:
T re, im;
// 友元
friend complex& __doapl<> (complex *ths, const complex& r);
};
// 使用内联函数加快编译速度
template<typename T>
inline T real (const complex<T>& r)
{
return r.real();
}
template<typename T>
inline T imag (const complex<T>& r)
{
return r.imag();
}
template<typename T>
inline complex<T>&
complex<T>::operator += (const complex<T>& r)
{
return __doapl(this, r);
}
#endif
用类模板实现复数类的时候需要注意以下几点:
- 友元在类外实现时必须先进行类的声明, 然后编写全局函数, 最后进行类的实现, 类的实现中需要进行友元的声明, 并且需要加上空模板的参数列表(否则会产生链接错误);
- 成员函数的类外实现均需要加上类模板定义;
- 养成写参数列表的习惯.
complex_by_template_test.cpp
#include <iostream>
#include "complex_by_template.h"
using namespace std;
// 格式化输出复数
// 重载 << 运算符
template<typename T>
ostream&
operator << (ostream& os, const complex<T>& x)
{
if (imag(x)<0)
return os << real(x) << '-' << -imag(x) <<'i';
else
return os << real(x) << '+' << imag(x) << 'i';
}
void test1(){
complex<int> c1(-3,-3);
complex<int> c2(3,2);
c2 += c1;
cout<<c2<<endl;
}
int main(int argc, char const *argv[])
{
test1();
return 0;
}
输出:
小结
注意一下类模板的一些实现细节, 就能得心应手了, 其实不是很复杂.