C ++中的模板类问题 [英] Problem with a template class in C++

查看:101
本文介绍了C ++中的模板类问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用命名空间的头文件中定义模板类时遇到问题,抱歉没有在描述标题中的问题时指定,但我现在没有关于它的任何内容,这是我的第一个模板类方式。

  #ifndef MYVECTOR_H_INCLUDED 
#define MYVECTOR_H_INCLUDED

命名空间 sam
{
模板< typename T> class MyVector
{
public
MyVector();
MyVector( int size);
MyVector(MyVector& other);
T get( int index);
int size();
void set( int index,T item);
void push_back(T item);
void push_front(T item);
MyVector& operator =( const MyVector& other);
~MyVector();
private
T growArray();
T * p_array;
int array_size;
};
模板< typename T> MyVector< T> ::〜MyVector()
{
delete p_array;
}

模板< typename T> int MyVector< T> :: size()
{
return array_size;
}

模板< typename T> MyVector< T> :: MyVector(MyVector& other)
{
this - > array_size = other.array_size;
- > p_array = new int [ARRAY_SIZE];
for int i = 0 ; i< array_size; i ++)
{
p_array [i] = other.p_array [i];
}
}

模板< typename T> MyVector&安培; MyVector< T> :: 运算符 =( const MyVector& other)
// 无效使用模板名称'sam :: MyVector'没有参数列表|
{
如果 ==& other)
{
return * ;
}
delete p_array;
- > p_array = new T [other.array_size];
- > array_size = other.array_size;
for int i = 0 ; i< other.array_size; i ++)
{
this - > p_array [i] = other.p_array [i] ;
}
返回 * ;
}
模板< typename T> void MyVector< T> :: push_front(T item)
{
if (p_array [ 0 ] == NULL)
{
p_array [ 0 ] =项目;
}
else
{
T * p_temp = new T [array_size + 1 ];
for int i = 1 ; i< = array_size; i ++)
{
p_temp [i] = p_array [i- 1 ];
}
growArray();
p_array = p_temp;
}
}

模板< typename T> void MyVector< T> :: push_back(T item)
{
if (p_array [array_size- 1 ] == NULL)
{
p_array [array_size- 1 ] = item;
}
else
{
growArray();
p_array [array_size] = item;
}
}

模板< typename T> MyVector< T> :: MyVector()
:array_size( 32
{
p_array = new int [ 32 ];
for int i = 0 ; i< 32 ; i ++)
{
p_array [i] = NULL;
}
}

模板< typename T> MyVector< T> :: MyVector( int size)
:array_size(size)
{
p_array = new int [size];
for int i = 0 ; i< size; i ++)
{
p_array [i] = NULL;
}
}

模板< typename T> T MyVector< T> :: get( int index)
{
if (index> = 0 && index< array_size)
{
if (p_array [index]!= NULL)
{
return p_array [index];
}
return 0 ;
}
其他
{
返回 0 ;
}
}

模板< typename T> T MyVector< T> :: growArray()
{
T * p_temp = new T [array_size + 1 ];
p_temp = p_array;
array_size ++;
delete p_array;
p_array = p_temp;
}

模板< typename T> void MyVector< T> :: set( int index,T item)
{
if (index> = 0 && index< array_size)
{
p_array [index] = item;
}
else if (index> array_size)
{
growArray();
p_array [array_size] = item;
}
其他
{
return ;
}
}
}

#endif // MYVECTOR_H_INCLUDED



我评论了错误信息,请帮助。



谢谢,Samuel。

解决方案

您的返回值还必须具有模板规范。



模板< typename T> MyVector< T> &安培; MyVector< T> :: operator =(const MyVector& other)


除了修复错误(参见解决方案1)之外,还有几个错误在代码中,其中一些是严重的:



1.有几次你分配内部数组调用 new int [] 而不是新T []



2.你的方法 grow_array( )有一些严重的问题:

 T * p_temp =  new  T [array_size +  1 ];  //   ok  
p_temp = p_array; // 泄漏错误1
array_size ++; / / ok
delete p_array; // 运行时错误2
p_array = p_temp; // 致命错误3
// error 4



- 错误1:你刚刚丢失了对新分配的数组的唯一引用 - 内存泄漏!解决方案:只需删除该行!

- 错误2:您必须使用delete [] p_array,否则会出现运行时错误。还有一个次要问题是您丢失了当前存储在p_array中的所有值。你不想将它们复制到新数组吗?

- 错误3:由于p_temp指向p_array所指向的相同地址,因此该行什么都不做。但是,它确实意味着p_array(仍)指向无效的内存,下次尝试使用它将导致致命的错误,导致程序崩溃!解决方案:修复错误后将修复1.

- 错误4:缺少return语句(但是,你似乎没有使用返回值,所以你也可以改变返回类型为 void



3.您的方法 push_front()调用 grow_array ,但也可以自行完成所需的分配。



4.方法 push_front push_back 查询 p_array 的值,而不检查是否甚至定义:如果 p_array 0 ,那么这可能会导致崩溃。



5.方法 set 使用 grow_array 以防索引超出范围,但如果索引超出范围超出1,这将是不够的。因此,该值可能存储在意外的位置!



和一个小问题:

您的默认构造函数分配一个默认长度的数组然后使用 NULL 初始化所有数组元素。你应该在这里使用 0 - 或者更好:

 p_array [i] = T(0); 


Hi, I have a problem with defining a template class in a header file with namespace, sorry for not being specified in describing the problem in the title but I don't now anything about it, It is my fist template class by the way.

#ifndef MYVECTOR_H_INCLUDED
#define MYVECTOR_H_INCLUDED

namespace sam
{
    template <typename T> class MyVector
    {
    public :
        MyVector();
        MyVector(int size);
        MyVector(MyVector& other);
        T get(int index);
        int size();
        void set(int index,T item);
        void push_back(T item);
        void push_front(T item);
        MyVector& operator= (const MyVector& other);
        ~MyVector();
    private :
        T growArray();
        T * p_array;
        int array_size;
    };
template <typename T> MyVector<T>::~MyVector()
{
    delete p_array;
}

template <typename T> int MyVector<T>::size()
{
    return array_size;
}

template <typename T> MyVector<T>::MyVector(MyVector& other)
{
    this->array_size = other.array_size;
    this->p_array = new int[array_size];
    for (int i = 0; i < array_size; i++)
    {
        p_array[i] = other.p_array[i];
    }
}

template <typename T> MyVector& MyVector<T>::operator=(const MyVector& other)
//invalid use of template-name 'sam::MyVector' without an argument list|
{
    if (this == &other)
    {
        return *this;
    }
    delete p_array;
    this->p_array = new T[other.array_size];
    this->array_size = other.array_size;
    for (int i = 0; i < other.array_size; i++)
    {
        this->p_array[i] = other.p_array[i];
    }
    return *this;
}
template <typename T> void MyVector<T>::push_front (T item)
{
    if (p_array[0] == NULL)
    {
        p_array[0] = item;
    }
    else
    {
        T * p_temp = new T[array_size + 1];
        for (int i = 1; i <= array_size; i++)
        {
            p_temp[i] = p_array[i-1];
        }
        growArray();
        p_array = p_temp;
    }
}

template <typename T> void MyVector<T>::push_back(T item)
{
    if (p_array[array_size-1] == NULL)
    {
        p_array[array_size-1] = item;
    }
    else
    {
        growArray();
        p_array[array_size] = item;
    }
}

template <typename T> MyVector<T>::MyVector()
:array_size(32)
{
    p_array = new int[32];
    for (int i = 0; i < 32; i++)
    {
        p_array[i] = NULL;
    }
}

template <typename T> MyVector<T>::MyVector(int size)
:array_size(size)
{
    p_array = new int[size];
    for (int i = 0; i < size; i++)
    {
        p_array[i] = NULL;
    }
}

template <typename T> T MyVector<T>::get(int index)
{
    if (index >= 0 && index < array_size)
    {
        if (p_array[index] != NULL)
        {
            return p_array[index];
        }
        return 0;
    }
    else
    {
        return 0;
    }
}

template <typename T> T MyVector<T>::growArray()
{
    T* p_temp = new T[array_size + 1];
    p_temp = p_array;
    array_size++;
    delete p_array;
    p_array = p_temp;
}

template <typename T> void MyVector<T>::set(int index,T item)
{
    if (index >= 0 && index < array_size)
    {
        p_array[index] = item;
    }
    else if (index > array_size)
    {
        growArray();
        p_array[array_size] = item;
    }
    else
    {
        return;
    }
}
}

#endif // MYVECTOR_H_INCLUDED


I commented the error message, Please Help.

Thanks, Samuel.

解决方案

Your return value must also have a template specification.

template <typename T> MyVector<T> & MyVector<T>::operator=(const MyVector& other)


In addition to the fix to your error (see solution 1), there are several errors in the code, some of them severe:

1. on several occasions you allocate your internal array calling new int[] rather than new T[]

2. your method grow_array() has some severe issues:

T* p_temp = new T[array_size + 1];//ok
p_temp = p_array;//leak error 1
array_size++;//ok
delete p_array;//runtime error 2
p_array = p_temp;//fatal error 3
// error 4


- error 1: you just lost your only reference to the newly allocated array - memory leak! Solution: just remove that line!
- error 2: you must use delete[] p_array, else you get a runtime error. There's also the secondary issue that you're losing all the values currently stored in p_array. Didn't you want to copy them to the new array?
- error 3: since p_temp is pointing to the same address p_array is pointing to, this line does nothing at all. However, it does mean that p_array is (still) pointing to invalidated memory, and the next attempt to use it will result in a fatal error that crashes the program! Solution: will be fixed after fixing error 1.
- error 4: the return statement is missing (but then, you don't appear to be using a return value, so you might just as well change the return type to void)

3. your method push_front() calls grow_array, but also redundandly does the required allocation itself.

4. The methods push_front and push_back query values of p_array without checking if it is even defined: if p_array is 0, then this may result in a crash.

5. the method set uses grow_array in case the index is out of range, but that won't be sufficient if the index is out of range by more than 1. Consequently, the value may be stored at an unexpected location!

And one minor issue:
Your default constructor allocates an array of default length and then initializes all array elements with NULL. You should be using 0 here - or better:

p_array[i] = T(0);


这篇关于C ++中的模板类问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆