Инициализация константного массива фиксированного размера внутри класса - PullRequest
4 голосов
/ 17 ноября 2011

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

class A {
    const int arr[2];
public:
      A() { }
};

Можно ли инициализировать arr из списка инициализатора конструктора или любым другим способом, кроме как в строке, где оно объявлено (т.е. const int arr[2] = {1,2};)?

Обратите внимание, что мне интересны методы, которые работают с C ++ 98!

Ответы [ 3 ]

4 голосов
/ 17 ноября 2011

Оборачивая их в 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;
    }
}
2 голосов
/ 17 ноября 2011

Инициализация элементов массива с ненулевыми значениями требует поддержки C ++ 11.

В C ++ 03 возможна только инициализация значения вашего массива, в результате чего значение каждого элемента равно 0:

class A {
    const int arr[2];
public:
    A() : arr() { }
};

Для соответствующего стандарта C ++ 03 см. Этот вопрос и ответ:
Как я могу использовать список инициализации члена для его инициализации?

(Я предполагаю, что под C ++ 98 вы подразумеваете , а не C ++ 11, то есть, что C ++ 03 приемлемо. Если это предположение неверно, скажите, пожалуйста.)

0 голосов
/ 17 ноября 2011

Нет.Это не так.

...