2

logic_error非プリミティブ型で使用された場合にをスローするジェネリック配列クラスがあります。

テンプレートクラス:

#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[];
};

テストコード:

動作中(使用されるプリミティブ型):

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

配列は次のように入力され0ます:Array{ 0, 0, 0, 0, 0 }

失敗(非プリミティブ型を使用):

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

スローされた例外:

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

これは、Arrayクラスで::fill_()呼び出されたときに発生します(/* 1 */)。

T各要素を反復処理せずに、配列全体をそのタイプのNull要素(intの場合は0、NULLポインターの場合など)で埋めたいと思います。memset()ここでは良い解決策ではありませんね。

4

1 に答える 1

4

これがあなたがすべきことです。これは、クラスの正しいスケルトンを持つ最小限のコードです。

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
};

デストラクタコピーコンストラクタ、およびコピー代入を定義する必要がある理由を知るには、ムーブコンストラクタムーブ代入を より適切に定義します。これらを(この順序で)参照してください。

于 2013-01-05T22:14:16.837 に答える