Инициализация константного массива фиксированного размера внутри класса

Рассмотрим следующий класс:

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 является приемлемым. Если это предположение неверно, скажите, пожалуйста.)

Нет, это не так.

Другие вопросы по тегам