C ++を学習するとき、Microsoftが提供する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で書かれたプログラムです。便宜上、これらのプログラムを1つのファイルに書き込みます。クラスの宣言、クラスの実現、およびmain関数の実現を3つのファイルに分割する場合は、 main関数には、クラスを実現するためのファイルが含まれています。つまり
、テンプレートクラスの宣言はahにあり、クラスの実現はa.cppにあり、main関数はmain.cppにあり、main.cppには#include "が含まれている必要があります。 「ah」ヘッダーファイルの代わりに「a.cpp」。これはほんの小さな詳細であり、Linux環境にも適用できます。
上記のプログラムでは、宣言部分にオーバーロードの<<演算子を追加して、テンプレートクラスをコンパイルして渡すようにしています。これは、VSコンパイラの実装に関連しており、<<演算子の実装を作成するときに書き込むことはできません。
Linuxはg ++コンパイラを使用し、g ++コンパイラのコンパイル原理はVSコンパイラのコンパイル原理とは異なるため、この同じプログラムをLinuxで実行することはできません。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 ++コンパイラを使用するときに記述されたコードです。インターネットで確認したもう1つのコードは、operator <<(...)の途中に<>を追加することです。つまり、operator << <>(...)このメソッドではできません。 g ++コンパイラをコンパイルして渡します。
g ++の左シフト演算子は、宣言時にクラスのテンプレート関数宣言を追加する必要があります。宣言のタイプは、クラスの宣言タイプと同じにすることはできません。つまり、Mytype宣言のフレンド関数の左シフト演算子は、実装のプログラムで使用されます。 Mytypeタイプを使用するか、Tタイプフラグを使用して左シフト演算子のオーバーロードを実装できます。ここでの選択は、クラス宣言フラグと同じです。