C++程序学习--C++模板类重载左移操作符<<的细节

来源:互联网 发布:数据集成 编辑:程序博客网 时间:2024/05/07 18:05

学习C++时,有时候我们会使用微软提供的VS软件,在学习到模板类重载左移操作符时会遇到一些问题,下面写一个简单的程序来举例:

#include <iostream>using namespace std;template<class T>class Complex{private:T a;public:Complex(T a);friend ostream & operator<< <T>(ostream & os, const Complex<T> & obj); //VS中特殊的标志<T>};template<class T>Complex<T>::Complex(T a){this->a = a;}template<class T>ostream & operator<<(ostream & os, const Complex<T> & obj){os << "a = " << obj.a;return os;}int main(int argc, char const *argv[]){Complex<int> c1(4);cout << c1 << endl; system("pause");return 0;}
该程序只是VS2010中写入的程序,为了方便,我将这些程序我都是写到一个文件中,如果要将类的声明和类的实现,还有主函数的实现分成三个文件,则必须在主函数中包含的是类的实现的文件,即:

模板类的声明在a.h中,类的实现在a.cpp中,主函数在main.cpp中,则main.cpp中必须包含#include "a.cpp"而不能是"a.h"头文件,这只是一个小细节,在Linux环境下同样适用。

上面程序中重载<<操作符时在声明的部分加入了<T>才能使模板类编译通过,这与VS编译器的实现有关,而且在写<<操作符的实现时不能再写<T>。

这个同样的程序在Linux下不能运行,因为Linux使用的是g++编译器,g++编译器的编译原理与VS的编译器编译原理不同。在Linux中,程序应该这样写:

#include <iostream>using namespace std;template<class T>class Complex{private:T a;public:Complex(T a);template<class Mytype> friend ostream & operator<<(ostream & os, const Complex<Mytype> & obj);//在使用g++编译器中需要加上类的的前置声明};template<class T>Complex<T>::Complex(T a){this->a = a;}template<class T>ostream & operator<<(ostream & os, const Complex<T> & obj) {os << "a = " << obj.a;return os;}/*template<class Mytype>ostream & operator<<(ostream & os, const Complex<Mytype> & obj){obj.count++;os << "count = " << obj.count << endl;os << "a = " << obj.c_a;return os;}*/int main(int argc, char const *argv[]){Complex<int> c1(8);cout << c1 << endl; return 0;}
这是在Linux下使用g++编译器时写的代码,其中我还在网上查阅的另外一种在operator<<(...)中间加上<>即:operator<< <>(...)这种方法不能再g++编译器中编译通过。

g++中左移操作符在声明的时候需要加上类的模板函数声明,且该声明的类型不能和类的声明类型相同,即程序中使用了Mytype声明友元函数左移操作符,在实现中既可以使用Mytype类型实现,也可以使用T类型标志来实现左移操作符的重载,这里选择和类的声明标志相同。

0 0
原创粉丝点击