这个模板程序有什么问题吗?
我一直在尝试学习 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.