1. 所有函数都写在类的内部
#include <iostream>
using namespace std;
//所有函数都写在类的内部没有出问题
template <typename T>
class Complex
{
friend ostream& operator<<(ostream& out, Complex& c)
{
out << c.a << " + " << c.b << "i" << endl;
return out;
}
friend Complex& MySub(Complex& c1, Complex& c2)
{
Complex tmp = Complex(c1.a - c2.a, c1.b - c2.b);
return tmp;
}
public:
Complex(T a, T b)
{
this->a = a;
this->b = b;
}
Complex operator + (Complex & c2)
{
Complex tmp = Complex(a + c2.a, b + c2.b);
return tmp;
}
private:
T a;
T b;
};
int main()
{
Complex<int> c1(3, 2), c2(4, 5);
Complex<int> c3 = MySub(c1, c2);
Complex<int> c4 = c1 + c2;
cout << c4 << endl;
cout << c3 << endl;
return 0;
}
2. 所有函数都写在类的外部(同一cpp中)
#include <iostream>
using namespace std;
//所有函数都写在类的内部没有出问题
template <typename T>
class Complex
{
friend ostream& operator<< <T>(ostream& out, Complex& c);//特别注意
public:
Complex(T a, T b);
Complex operator + (Complex& c2);
Complex MySub(Complex& c);
private:
T a;
T b;
};
template<typename T>
Complex<T>::Complex(T a, T b)
{
this->a = a;
this->b = b;
}
template <typename T>
Complex<T> Complex<T>::operator+(Complex<T>& c2)
{
Complex tmp(a + c2.a, b + c2.b);
return tmp;
}
template<typename T>
Complex<T> Complex<T>::MySub(Complex& c)
{
Complex tmp(a - c.a, b - c.b);
return tmp;
}
template <typename T>
ostream& operator<<(ostream& out, Complex<T>& c)
{
out << c.a << " + " << c.b << "i" << endl;
return out;
}
int main()
{
Complex<int> c1(3, 2), c2(4, 5);
Complex<int> c3 = c1.MySub(c2);
Complex<int> c4 = c1 + c2;
cout << c4 << endl;
cout << c3 << endl;
return 0;
}
特别需要注意,在类外部实现重载<<
时,要加上声明<T>
,这是C++编译器的一个弊端,但始终没有修复
3. 所有函数都写在类的外部(.h和.cpp分开)
复数类_所有函数写在类的外部(h和cpp分开).h
#include <iostream>
using namespace std;
template <typename T>
class Complex
{
friend ostream& operator<< <T>(ostream& out, Complex& c);//特别注意
public:
Complex(T a, T b);
Complex operator + (Complex& c2);
Complex MySub(Complex& c);
private:
T a;
T b;
};
复数类_所有函数写在类的外部(h和cpp分开).hpp
#pragma once
#include <iostream>
#include "复数类_所有函数写在类的外部(h和cpp分开).h"
using namespace std;
template<typename T>
Complex<T>::Complex(T a, T b)
{
this->a = a;
this->b = b;
}
template <typename T>
Complex<T> Complex<T>::operator+(Complex<T>& c2)
{
Complex tmp(a + c2.a, b + c2.b);
return tmp;
}
template<typename T>
Complex<T> Complex<T>::MySub(Complex& c)
{
Complex tmp(a - c.a, b - c.b);
return tmp;
}
template <typename T>
ostream& operator<<(ostream& out, Complex<T>& c)
{
out << c.a << " + " << c.b << "i" << endl;
return out;
}
dm09_复数类_main.cpp
#pragma once
#include <iostream>
#include "复数类_所有函数写在类的外部(h和cpp分开).hpp"
using namespace std;
int main()
{
Complex<int> c1(3, 2), c2(4, 5);
Complex<int> c3 = c1.MySub(c2);
Complex<int> c4 = c1 + c2;
cout << c4 << endl;
cout << c3 << endl;
return 0;
}
特别需要注意,包含头文件时必须包含实现的函数体.hpp
(不成文规定)。
原因:二次编译惹的祸。