2013-06-21 1 views
3

мне нужно реализовать безопасный класс массива, который контролирует индекс при доступе к лежащей в основе массива C:ИНИЦИАЛИЗИРУЙТЕ C++ элемент массива в шаблоне класса

template <typename T, int N> class SafeArray 
{ 
public: 
    T &operator[](int index) 
    { 
     assert(0 <= index && index < N); 
     return m_data[index]; 
    } 
private: 
    T m_data[N]; 
}; 

И вместо bool a[3];, теперь я пишу SafeArray<bool, 3> a;.

Как поддерживать инициализацию массива, например bool b[3] = {false};? Я имею в виду, что мне следует сделать, чтобы получить b.m_data[] = {false, false, false} после того, как был создан SafeArray<bool, 3> b;?

Я предполагаю, что я должен добавить конструктор в SafeArray, но что будет телом этого конструктора? Параметр шаблона T может быть любым, не обязательно bool. Я использую pre-C++ 11.

+0

станд :: initializer_list .Проверить один из моих [вопросов] (http://stackoverflow.com/questions/16455029/how-to-implement-an-initializer-list-for-user-defined -typeanalogus-to-stdvec) –

+1

Вы хотите повторно реализовать std :: array <>? Вы можете использовать именно это, а не учиться на чтении источника –

+0

для pre-C++ 11, я чувствовал, что вы можете что-то сделать, подготовив шаблон инициализации для каждой длины.шаблон init для длины 2 будет использовать шаблон инициализации для длины 1 плюс еще один. упоминается где-то, возможно, в Modern C++ Design Alexandrescu –

ответ

1

Я имею в виду, что мне делать, чтобы получить b.m_data[] = {false, false, false} после того, как SafeArray<bool, 3> b; был построен?

Я не уверен, что я правильно понимаю ваш вопрос, но если я делаю, то все, что вам нужно сделать, это писать конструктор по умолчанию, который инициализирует ваш массив:

SafeArray() : m_data() 
{ 
} 

Полный код:

template <typename T, int N> class SafeArray 
{ 
public: 
    SafeArray() : m_data() 
    { 
    } 
    T &operator[](int index) 
    { 
     assert(0 <= index && index < N); 
     return m_data[index]; 
    } 
private: 
    T m_data[N]; 
}; 

И live example.

+1

Не будет 'SafeArray(): m_data() {}' так трюк, без вызова 'std :: fill'? – juanchopanza

+0

@juanchopanza: D'oh! Да, ты прав. Переход к редактированию, спасибо –

0

Поскольку вы используете C++ 03 (поэтому у вас нет std::array) Я бы предпочел рекомендовать вам boost::array, который является, в основном, реализацией C++ 03 std::array. (Фактически, std::array был вдохновлен boost::array).

В противном случае, сделайте ваш класс агрегат, то есть (как в C++ 03 8.5.1/1)

Агрегат представляет собой массив или класс (пункт 9) без пользователя -declared, без частного защищенного нестатического элемента данных (раздел 11), без базовых классов (раздел 10) и без виртуальных функций.

Тогда ваш класс будет поддерживать агрегатную инициализацию по вашему желанию.

Обновление: Чтение OP снова (и Andy Prowl «s answer), я не уверен, что понял вопрос. То, что я предлагаю здесь способ инициализации SafeArray во время строительства, например,

SafeArray<bool, 3> b = { false, false, false }; 
+0

Я тоже об этом подумал, но я думаю, что OP хочет гарантировать безопасный доступ, поэтому им нужно сохранить частный элемент данных массива - и это делает класс неагрегатом –

+0

@ Andy Prowl: Good точка. Спасибо. –

0

Как насчет ...?

SafeArray() { 
    for (int i = 0; i < N; ++i) { 
     m_data[i] = T(); 
    } 
}