我自定义了一个模板类并重载了运算符,预定义实现功能为能实现对数组一般操作,类似于vector。
#ifndef ARRAY_H #define ARRAY_H #include <iostream> using namespace std; template<class T> class Array{ friend ostream& operator<<(ostream&, const Array &); friend istream& operator>>(istream&, Array &); public: Array(int arraySize = 10){ size = (arraySize > 0 ? arraySize : 10); ptr = new T[size]; for (int i = 0; i < size; i++) ptr[i] = 0; } Array(const Array &arrayToCopy){ ptr = new int[size]; for (int i = 0; i < size; i++){ ptr[i] = arrayToCopy[i]; } } ~Array(){ delete[] ptr; } int getSize()const{ return size; } const Array& operator=(const Array &right){ if (&right != this){ if (size != right.size){ delete[] ptr; size = right.size; ptr = new T[size]; } for (int i = 0; i < size; i++) ptr[i] = right.ptr[i]; } return *this; } bool operator==(const Array &right)const{ if (size != right.size) return false; for (int i = 0; i < size; i++) if (ptr[i] != right.ptr[i]) return false; return true; } bool operator!=(const Array &right)const{ return !(*this == right); } T& operator[](int subscript) { if (subscript < 0 || subscript >= size){ cerr << "\nError: Subscript " << subscript << "out of range" << endl; exit(1); } return ptr[subscript]; } T operator[](int subscript)const{ if (subscript < 0 || subscript >= size) { cerr << "\nError: Subscript" << subscript << "out of range" << endl; exit(1); } return ptr[subscript]; } private: int size; T *ptr; }; #endif template<class T> istream& operator>>(istream &input, Array<T> &a){ for (int i = 0; i < a.size; i++) input >> a.ptr[i]; return input; } template<class T> ostream& operator<<(ostream &output, const Array<T> &a){ int i; for (i = 0; i < a.size; i++){ output << setw(12) << a.ptr[i]; if ((i + 1) % 4 == 0) ouput << endl; } if (i % 4 != 0) output << endl; return output; }
#include <iostream> #include "Array.h" using namespace std; int main(){ Array<int> integers1(7); cout << "Size of Array integers1 is " << integers1.getSize() << "\nArray after initialization:\n"<< integers1; }出错错误原因为
1>main.obj : error LNK2019: 无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Array<int> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$Array@H@@@Z),该符号在函数 _main 中被引用
我猜测的原因是cin为ostream对象实例,但是没对我自定义的类型进行<<重载。不知道我的猜测对不对,希望有经验的人给我点文档与链接。
问题已经得到解决,
模板类中的友元函数需要进行特别的处理。原因请参考我的博文。
http://blog.csdn.net/u010003835/article/details/47312955
设置友元后
头文件
#ifndef ARRAY_H #define ARRAY_H #include <iostream> #include <iomanip> using namespace std; //模板类前置声明 template<class T> class Array; //Array模板类的友元声明 template<class T> istream& operator>>(istream& input, Array<T>& a); template<class T> ostream& operator<<(ostream& output, const Array<T>& a); template<class T> class Array{ friend ostream& operator<< <> (ostream&, const Array<T>&); friend istream& operator>> <> (istream&, Array<T>&); public: Array(int arraySize = 10){ size = (arraySize > 0 ? arraySize : 10); ptr = new T[size]; for (int i = 0; i < size; i++) ptr[i] = 0; } Array(const Array &arrayToCopy){ ptr = new int[size]; for (int i = 0; i < size; i++){ ptr[i] = arrayToCopy[i]; } } ~Array(){ delete[] ptr; } int getSize()const{ return size; } const Array& operator=(const Array &right){ if (&right != this){ if (size != right.size){ delete[] ptr; size = right.size; ptr = new T[size]; } for (int i = 0; i < size; i++) ptr[i] = right.ptr[i]; } return *this; } bool operator==(const Array &right)const{ if (size != right.size) return false; for (int i = 0; i < size; i++) if (ptr[i] != right.ptr[i]) return false; return true; } bool operator!=(const Array &right)const{ return !(*this == right); } T& operator[](int subscript) { if (subscript < 0 || subscript >= size){ cerr << "\nError: Subscript " << subscript << "out of range" << endl; exit(1); } return ptr[subscript]; } T operator[](int subscript)const{ if (subscript < 0 || subscript >= size) { cerr << "\nError: Subscript" << subscript << "out of range" << endl; exit(1); } return ptr[subscript]; } private: int size; T *ptr; }; #endif template<class T> istream& operator>>(istream &input, Array<T> &a){ for (int i = 0; i < a.size; i++) input >> a.ptr[i]; return input; } template<class T> ostream& operator<<(ostream &output, const Array<T> &a){ int i; for (i = 0; i < a.size; i++){ output << setw(12) << a.ptr[i]; if ((i + 1) % 4 == 0) output << endl; } if (i % 4 != 0) output << endl; return output; }
正确的写法就是代码段中的写法。<>也必不可少,其实<>有两
重意思:
一是,表明此友元函数是函数模板;
二是,此模板使用的模板类型参数为当前
模板类的类型参数class。
主函数
<pre name="code" class="cpp">#include "Array.h" using namespace std; int main(){ Array<int> integers1(7); Array<int> integers2; Array<char> char_string(100); cout << "Size of Array integers1 is " << integers1.getSize() << "\nArray after initialization:\n" << integers1 << endl; cout << "Size of Array char_string is " << char_string.getSize() << "\nArray after initialization:\n" << endl; if (integers1 != integers2) cout << "integers1 and integers2 are not equal" << endl; cout << "\ninteger2[5] is " << integers2[5] << endl; }
运行截图
第二种方法
#ifndef ARRAY_H #define ARRAY_H #include <iostream> #include <iomanip> using namespace std; //模板类前置声明 template<class T> class Array; //Array模板类的友元声明 template<class S> istream& operator>>(istream& input, Array<S>& a); template<class S> ostream& operator<<(ostream& output, const Array<S>& a); template<class T> class Array{ template<class S> friend ostream& operator<<(ostream&, const Array<S>&); template<class S> friend istream& operator>>(istream&, Array<S>&); public: Array(int arraySize = 10){ size = (arraySize > 0 ? arraySize : 10); ptr = new T[size]; for (int i = 0; i < size; i++) ptr[i] = 0; } Array(const Array &arrayToCopy){ ptr = new int[size]; for (int i = 0; i < size; i++){ ptr[i] = arrayToCopy[i]; } } ~Array(){ delete[] ptr; } int getSize()const{ return size; } const Array& operator=(const Array &right){ if (&right != this){ if (size != right.size){ delete[] ptr; size = right.size; ptr = new T[size]; } for (int i = 0; i < size; i++) ptr[i] = right.ptr[i]; } return *this; } bool operator==(const Array &right)const{ if (size != right.size) return false; for (int i = 0; i < size; i++) if (ptr[i] != right.ptr[i]) return false; return true; } bool operator!=(const Array &right)const{ return !(*this == right); } T& operator[](int subscript) { if (subscript < 0 || subscript >= size){ cerr << "\nError: Subscript " << subscript << "out of range" << endl; exit(1); } return ptr[subscript]; } T operator[](int subscript)const{ if (subscript < 0 || subscript >= size) { cerr << "\nError: Subscript" << subscript << "out of range" << endl; exit(1); } return ptr[subscript]; } private: int size; T *ptr; }; #endif template<class T> istream& operator>>(istream &input, Array<T> &a){ for (int i = 0; i < a.size; i++) input >> a.ptr[i]; return input; } template<class T> ostream& operator<<(ostream &output, const Array<T> &a){ int i; for (i = 0; i < a.size; i++){ output << setw(12) << a.ptr[i]; if ((i + 1) % 4 == 0) output << endl; } if (i % 4 != 0) output << endl; return output; }