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,请参阅这些(按此顺序):
- What is The Rule of Three?
- Rule-of-Three becomes Rule-of-Five with C++11?
什么是三法则?
使用C ++ 11,三次规则成为五次规则?
#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,请参阅这些(按此顺序):
- What is The Rule of Three?
- Rule-of-Three becomes Rule-of-Five with C++11?
什么是三法则?
使用C ++ 11,三次规则成为五次规则?