如果使用非基本类型,则清除通用数组会抛出logic_error

时间:2022-12-05 21:40:52

I have a generic array class which throws a logic_error if it's used with a non-primitive type.

我有一个泛型数组类,如果它与非基本类型一起使用,则抛出一个logic_error。

Template Class:

#include <string>
#include <sstream>
#include <iostream>    

using namespace std;

#define NULL_ELEMENT        ((T)NULL)


template<class T> class Array
{    
public:    
    Array(const int size)
    {
        this->elements[size];
        this->size = size;
        ::fill_n(elements, size, NULL_ELEMENT); /* 1 */
    }


    // Output of the array
    string toString()
    {
        int i=0;
        stringstream ss;

        ss << "Array{ ";

        for( ; i<size-1; i++ )
        {
            ss << elements[i] << ", ";
        }

        ss << elements[i] << " }";

        return ss.str();
    }

    // ...

private:
    int size;
    T elements[];
};

Test Code:

Working (primitive type used):

工作(使用原始类型):

Array<int> arr(5);
cout << arr.toString() << endl;

Array is filled with 0: Array{ 0, 0, 0, 0, 0 }

数组填充0:数组{0,0,0,0,0}

Fail (non-primitive type used):

失败(使用非原始类型):

Array<string> arr(size); // <-- Exception thrown here
cout << arr.toString() << endl;

Thrown Exception:

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_S_construct null not valid

This happens in Array class at when ::fill_() is called (/* 1 */).

这在调用when :: fill_()时的Array类中发生(/ * 1 * /)。

I want to fill the whole array with the Null-Element of the type T (like 0 if int or NULL if pointer etc.) - without iterating over each element. memset() is not a good solution here, isnt it?

我想用T类型的Null-Element填充整个数组(如果是int则为0或者如果指针等则为NULL) - 不迭代每个元素。 memset()在这里不是一个好的解决方案,不是吗?

1 个解决方案

#1


4  

Here is what you should be doing. This is minimal code with correct skeleton of your class.

这是你应该做的。这是具有正确的类骨架的最小代码。

template<class T> 
class Array
{
     T  *m_elements;  //declare a pointer member 
     size_t m_size;   //count of the elements

public:    

    Array(size_t size) : m_size(size), m_element(new T[size]())
    {                // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                     //    use member-initialization-list
    }

    ~Array(); //must define it

    Array(Array const & other); //must define it

    Array& operator=(Array const & other); //must define it

    Array(Array&& temporary); //better define it (in C++11)
    Array& operator=(Array&& temporary); //better define it (in C++11)

    //other
};

To know why you must define the destructor, copy-constructor and copy-assignment, better define move-constructor and move-assignment, see these (in that order):

要知道为什么必须定义析构函数,复制构造函数和复制赋值,更好地定义move-constructor和move-assignment,请参阅这些(按此顺序):

#1


4  

Here is what you should be doing. This is minimal code with correct skeleton of your class.

这是你应该做的。这是具有正确的类骨架的最小代码。

template<class T> 
class Array
{
     T  *m_elements;  //declare a pointer member 
     size_t m_size;   //count of the elements

public:    

    Array(size_t size) : m_size(size), m_element(new T[size]())
    {                // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                     //    use member-initialization-list
    }

    ~Array(); //must define it

    Array(Array const & other); //must define it

    Array& operator=(Array const & other); //must define it

    Array(Array&& temporary); //better define it (in C++11)
    Array& operator=(Array&& temporary); //better define it (in C++11)

    //other
};

To know why you must define the destructor, copy-constructor and copy-assignment, better define move-constructor and move-assignment, see these (in that order):

要知道为什么必须定义析构函数,复制构造函数和复制赋值,更好地定义move-constructor和move-assignment,请参阅这些(按此顺序):