Инициализация константного массива фиксированного размера внутри класса
Рассмотрим следующий класс:
class A {
const int arr[2];
public:
A() { }
};
Можно ли инициализировать arr
из списка инициализатора конструктора или любым другим способом, кроме строки, где он объявлен (т.е. const int arr[2] = {1,2};
)?
Обратите внимание, что мне интересны методы, которые работают с C++98!
3 ответа
Заворачивая их в struct
Например:
class A
{
struct Data
{
int arr[2];
};
Data const arr;
public:
A() : arr( someOtherStruct ) {}
};
Это означает, что для доступа к данным вам нужно написать arr.arr
, Этого можно избежать, наследуя от struct
:
struct PrivateDataForA
{
int arr[2];
};
class A : private PrivateDataForA
{
public:
A() : PrivateDataForA( someOtherStruct ) {}
};
Это делает имя struct
видимый за пределами класса (что может быть преимуществом - клиентский код может передавать его в качестве аргумента).
Если у вас нет экземпляра полезной структуры, скажем, потому что вы хотите заполнить его значениями, вычисленными из аргументов конструктора, вы можете использовать статическую функцию-член:
class A : private PrivateDataForA
{
static PrivateDataForA createInitializer( int a, int b );
public:
A( int a, int b ) : PrivateDataForA( createInitializer( a, b ) )
{
}
};
Для конкретного примера ОП:
#include <iostream>
#include <stddef.h>
typedef ptrdiff_t Size;
typedef Size Index;
template< class Element, Size n >
struct Array{ Element elem[n]; };
class A {
Array<int, 2> const arr_; // const int arr[2];
A& operator=( A const& ); // No such.
static Array<int, 2> const& oneAndTwo()
{
static Array<int, 2> const a = {1, 2};
return a;
}
public:
A(): arr_( oneAndTwo() ) {}
int at( Index i ) const { return arr_.elem[i]; }
};
int main()
{
using namespace std;
A o;
for( int i = 0; i < 2; ++i )
{
cout << o.at( i ) << endl;
}
}
Инициализация элементов массива с ненулевыми значениями требует поддержки C++11.
В C++03 возможно только инициализировать значение вашего массива, в результате чего значение каждого элемента будет 0
:
class A {
const int arr[2];
public:
A() : arr() { }
};
Для соответствующего стандарта C++03 см. Этот вопрос и ответ:
Как я могу использовать список инициализации члена для его инициализации?
(Я собираюсь предположить, что под C++98 вы подразумеваете не C++11, то есть, что C++03 является приемлемым. Если это предположение неверно, скажите, пожалуйста.)