这个模板程序有什么问题吗?
我一直在尝试学习 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;
}
I've been trying to learn templates in C++ but I'm getting a little confused with what I'm doing wrong. I was told how to declare friend templates on a FAQ about templates and I had to do that with the overloaded operators but it seems to be giving me trouble telling me I have an invalid amount of arguments(I should have 2) in my Array.cpp. Is there any way I could fix this while keeping my operators. Also, is the simple main file the correct syntax for the templates?
Thank you.
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<<
My main file:
#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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
除了 MSN 指出的“模板源应该位于标头中”之外,源文件中重载流运算符的行还列出为:
然而,您尝试完成的操作的正确语法是使用的语法在头文件中:
头文件中的声明通常称为非成员流运算符。但是,源文件中的定义了一个成员移位运算符,该运算符不能用于流式传输,并且必须只有 1 个参数。
如果您更改声明以匹配头文件,则应该可以消除编译器问题。也就是说,您还需要将源文件的所有内容放入头文件或包含在第一个文件末尾的单独头文件中。如果不这样做,当您尝试创建可执行文件时,您将收到链接器错误。
In addition to the 'Template sources should be in headers' as pointed out by MSN, the lines for your overloaded stream operators in the source file are listed as:
However, the correct syntax for what you're attempting to accomplish is the one used in your header file:
The declarations in your header file are generally refered to as the non-member stream operators. However, the ones in your source file are defining a member shift operator, which cannot be used for streaming, and must have only 1 argument.
If you change the declarations to match the header file, it should eliminate your compiler problem. That said, you will also need to place all of the contents of your source file into your header file or into a separate header which is included at the end of the first. If you do not, you will get linker errors when you try to create your executable.
您将模板的实现放在单独的文件中,而不显式实例化您正在参数化的类型。
换句话说,您要么需要为您正在使用的类型显式实例化 Array 模板,要么需要通过模板声明使模板定义可用。即,将 .cpp 中的所有内容放入标头中。
You are putting the implementation of your template in a separate file without explicitly instantiating the types you are parameterizing.
In other words, you either need to explicitly instantiate the
Array
template for the types you are using or you need to make the template definition available with the template declaration. I.e., put all that stuff in the .cpp into the header.声明:
定义:
这些应该匹配。顺便说一句,声明是正确的。这也适用于 ostream 运算符
declaration:
definition:
These should match. The declaration one is right, btw. This also applies to the ostream operator
istream &Array::operator>>( istream &input, Array &a )
不应位于Array
类中。这样,它需要一个隐式的
this
参数,但您在&a
中显式传递所需的数组。将该行(以及相应的
operator<<
)更改为istream &operator>>(istream &input, Array&a)
它应该编译。由于函数重载,这不会与其他 istream 运算符混淆。istream &Array<T>::operator>>( istream &input, Array &a )
shouldn't be in theArray<T>
class.With it like that it takes an implicit
this
argument, but you're explicitly passing the array you want in&a
.Change that line (and the corresponding
operator<<
, equivalently) toistream &operator>>(istream &input, Array<T> &a)
and it should compile. This won't mess with otheristream
operators because of function overloading.