这个模板程序有什么问题?
What is wrong with this template program?
我一直在尝试学习c++模板,但我对我做错的事情有点困惑。我被告知如何在关于模板的FAQ上声明朋友模板,我不得不使用重载操作符这样做,但它似乎给我带来了麻烦,告诉我我在Array.cpp中有无效的参数(我应该有2个)。有什么办法能在保住我的操作员的同时解决这个问题吗。此外,简单的主文件是模板的正确语法吗?
谢谢。
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;
}
除了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 )
头文件中的声明通常称为非成员流操作符。但是,源文件中的那些定义了一个成员移位操作符,它不能用于流,并且必须只有一个参数。
如果您更改声明以匹配头文件,则应该可以消除编译器问题。也就是说,您还需要将源文件的所有内容放入头文件或包含在第一个文件末尾的单独头文件中。如果您不这样做,当您尝试创建您的可执行文件时,您将得到链接器错误。
您将模板的实现放在一个单独的文件中,而没有显式地实例化您要参数化的类型。
换句话说,您要么需要显式地为您正在使用的类型实例化Array
模板,要么需要通过模板声明使模板定义可用。也就是说,把。cpp文件中的所有内容放到header中。
声明:
template<typename T> istream &operator>>( istream &, Array<T> & );
定义:
istream &Array<T>::operator>>( istream &input, Array &a )
{
应该匹配。顺便说一句,声明一是对的。这也适用于ostream操作符
istream &Array<T>::operator>>( istream &input, Array &a )
不应该在Array<T>
类中。
就像这样,它需要一个隐式的this
参数,但你显式地传递你想要的&a
数组。
将该行(以及相应的operator<<
)更改为istream &operator>>(istream &input, Array<T> &a)
,它应该可以编译。这不会因为函数重载而与其他istream
操作符混淆。
- 警告处理为错误这里有什么问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 当我尝试添加 2 个大字符串时,我无法弄清楚出了什么问题
- 违反const正确性:我应该现实地期待什么问题
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- 我的逻辑反转字符串中的元音有什么问题?
- 需要以下代码的帮助,下面的代码有什么问题
- 常量公共成员有什么问题?
- 以下代码中的函数模板有什么问题?
- 这个返回元素位置的基于循环的函数有什么问题?
- creat_list2功能有什么问题?
- 格式说明符C++有什么问题
- 任何人都可以告诉我我的 C++ 代码出了什么问题?
- 从 argv[1] 转换为字符 * 字符串后有什么问题?
- 我的堆栈和库存清单程序的结构有什么问题?
- 此工厂功能有什么问题?
- 以下 C++ 代码有什么问题?
- 数组为此合并排序函数提供了正确的输出,但向量给出了不正确的输出.出了什么问题?
- reinterpret_cast,只读访问,简单的可复制类型,会出什么问题?
- 它解决了什么问题,对于非真空初始化,生命周期在初始化之前就开始了