我一直在尝试用C ++学习模板,但是我对我做错了什么感到困惑。我被告知如何在关于模板的常见问题解答中声明朋友模板,我必须使用重载的运算符来执行此操作,但它似乎让我很难告诉我在我的数组中有无效的参数(我应该有2个)。 CPP。有什么办法可以解决这个问题,同时保留我的操作员。另外,简单的主文件是模板的正确语法吗?
谢谢。
Array.h:
#ifndef ARRAY_H
#define ARRAY_H
#include <stdexcept>
#include <iostream>
using namespace std;
template<typename T> class Array;
template<typename T> ostream &operator<<( ostream &, const Array<T> & );
template<typename T> istream &operator>>( istream &, Array<T> & );
template< typename T >
class Array
{
friend ostream &operator<< <> ( ostream &, const Array<T> & );
friend istream &operator>> <> ( istream &, Array<T> & );
public:
Array( int = 10 );
Array( const Array & );
~Array();
int getSize() const;
const Array &operator=( const Array & );
bool operator==( const Array & ) const;
bool operator!=( const Array &right ) const
{
return ! ( *this == right );
}
T &operator[]( T );
T operator[]( T ) const;
private:
int size;
T *ptr;
};
#endif
Array.cpp
#include <iostream>
#include <iomanip>
#include <cstdlib> // exit function prototype
#include "Array.h" // Array class definition
using namespace std;
template< typename T >
Array<T>::Array( int arraySize )
{
if ( arraySize > 0 )
size = arraySize;
else
throw invalid_argument( "Array size must be greater than 0" );
ptr = new T[ size ];
for ( int i = 0; i < size; ++i )
ptr[ i ] = 0;
}
template< typename T >
Array<T>::Array( const Array &arrayToCopy )
: size( arrayToCopy.size )
{
ptr = new T[ size ];
for ( int i = 0; i < size; ++i )
ptr[ i ] = arrayToCopy.ptr[ i ];
}
template< typename T >
Array<T>::~Array()
{
delete [] ptr;
}
template< typename T >
int Array<T>::getSize() const
{
return size;
}
template< typename T >
const Array<T> &Array<T>::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;
}
template< typename T >
bool Array<T>::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;
}
template< typename T >
T &Array<T>::operator[]( T subscript )
{
if ( subscript < 0 || subscript >= size )
throw out_of_range( "Subscript out of range" );
return ptr[ subscript ];
}
template< typename T >
T Array<T>::operator[]( T subscript ) const
{
if ( subscript < 0 || subscript >= size )
throw out_of_range( "Subscript out of range" );
return ptr[ subscript ];
}
// overloaded input operator for class Array;
// inputs values for entire Array
template< typename T >
istream &Array<T>::operator>>( istream &input, Array &a )
{
for ( int i = 0; i < a.size; ++i )
input >> a.ptr[ i ];
return input; // enables cin >> x >> y;
} // end function
// overloaded output operator for class Array
template< typename T>
ostream &Array<T>::operator<<( ostream &output, const Array &a )
{
int i;
// output private ptr-based array
for ( i = 0; i < a.size; ++i )
{
output << setw( 12 ) << a.ptr[ i ];
if ( ( i + 1 ) % 4 == 0 ) // 4 numbers per row of output
output << endl;
} // end for
if ( i % 4 != 0 ) // end last line of output
output << endl;
return output; // enables cout << x << y;
} // end function operator<<
我的主要档案:
#include <iostream>
#include "Array.h"
using namespace std;
int main()
{
Array<int> integers1( 7 ); // seven-element Array
Array<int> integers2; // 10-element Array by default
// print integers1 size and contents
cout << "Size of Array integers1 is "
<< integers1.getSize()
<< "\nArray after initialization:\n" << integers1;
}
答案 0 :(得分:2)
除了MSN指出的'模板源应该在标题中'之外,源文件中重载流运算符的行列为:
template<typename T> istream &Array<T>::operator>>( istream &input, Array &a )
template<typename T> ostream &Array<T>::operator<<( ostream &output, const Array &a )
但是,您尝试完成的内容的正确语法是头文件中使用的语法:
template<typename T> istream &operator>>( istream &input, Array<T> &a )
template<typename T> ostream &operator<<( ostream &output, const Array<T> &a )
头文件中的声明通常被称为非成员流操作符。但是,源文件中的那些是定义成员移位运算符,不能用于流式传输,并且必须只有1个参数。
如果更改声明以匹配头文件,则应该消除编译器问题。也就是说,您还需要将源文件的所有内容放入头文件或单独的标题中,该标题包含在第一个文件的末尾。如果不这样做,则在尝试创建可执行文件时会出现链接器错误。
答案 1 :(得分:1)
您将模板的实现放在单独的文件中,而不显式实例化您要参数化的类型。
换句话说,您需要为正在使用的类型显式实例化Array
模板,或者需要使用模板声明使模板定义可用。即,将.cpp中的所有内容放入标题中。
答案 2 :(得分:1)
istream &Array<T>::operator>>( istream &input, Array &a )
不应该在Array<T>
课程中。
就像这样,它需要一个隐式的this
参数,但你明确地在&a
中传递了你想要的数组。
将该行(以及相应的operator<<
等效地)更改为istream &operator>>(istream &input, Array<T> &a)
,它应该编译。由于函数重载,这不会与其他istream
运算符混淆。
答案 3 :(得分:1)
声明:
template<typename T> istream &operator>>( istream &, Array<T> & );
定义:
istream &Array<T>::operator>>( istream &input, Array &a )
{
这些应该匹配。声明一个是对的,顺便说一下。这也适用于ostream运算符