这个模板程序有什么问题吗?

发布于 2024-12-09 15:09:12 字数 4790 浏览 0 评论 0原文

我一直在尝试学习 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

挥剑断情 2024-12-16 15:09:12

除了 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 个参数。

如果您更改声明以匹配头文件,则应该可以消除编译器问题。也就是说,您还需要将源文件的所有内容放入头文件或包含在第一个文件末尾的单独头文件中。如果不这样做,当您尝试创建可执行文件时,您将收到链接器错误。

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:

template<typename T> istream &Array<T>::operator>>( istream &input, Array &a )
template<typename T>  ostream &Array<T>::operator<<( ostream &output, const Array &a ) 

However, the correct syntax for what you're attempting to accomplish is the one used in your header file:

template<typename T> istream &operator>>( istream &input, Array<T> &a )
template<typename T> ostream &operator<<( ostream &output, const Array<T> &a ) 

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.

初相遇 2024-12-16 15:09:12

您将模板的实现放在单独的文件中,而不显式实例化您正在参数化的类型。

换句话说,您要么需要为您正在使用的类型显式实例化 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.

暗恋未遂 2024-12-16 15:09:12

声明:

template<typename T> istream &operator>>( istream &, Array<T> & );

定义:

istream &Array<T>::operator>>( istream &input, Array &a )
{

这些应该匹配。顺便说一句,声明是正确的。这也适用于 ostream 运算符

declaration:

template<typename T> istream &operator>>( istream &, Array<T> & );

definition:

istream &Array<T>::operator>>( istream &input, Array &a )
{

These should match. The declaration one is right, btw. This also applies to the ostream operator

倦话 2024-12-16 15:09:12

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 the Array<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) to istream &operator>>(istream &input, Array<T> &a) and it should compile. This won't mess with other istream operators because of function overloading.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文