c++日记——WIndows和Linux下左移模板函数的不同

学习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环境下同样适用。

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

这个同样的程序在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类型标志来实现左移操作符的重载,这里选择和类的声明标志相同。

猜你喜欢

转载自blog.csdn.net/qq_32198277/article/details/77623270
今日推荐