Проблемы при инициализации члена класса шаблона - PullRequest
0 голосов
/ 21 сентября 2010

Мой код не компилируется. Ниже мой код

template <typename T>

class TemplateClass
{

    const T constMember;
    public:

    TemplateClass()
    {
        constMember = T();
    }

};

int main()
{
   TemplateClass <int> obj;
}

Я получаю эту ошибку:

error: uninitialized member 'TemplateClass<int>::constMember' with 'const' type 'const int'

Я думал, что конструктор используется для инициализации членов данных. Что не так ????

Ответы [ 2 ]

11 голосов
/ 21 сентября 2010

Вы не инициализируете константный член, вы просто присваиваете ему.

Инициализация членов может быть выполнена только с использованием списка инициализации члена .

Дляпример:

TemplateClass() : constMember(T()) //initializes constMember to 0
{} 
4 голосов
/ 21 сентября 2010

Прасун уже дал вам очень хороший ответ .Тем не менее, я хотел бы сделать еще одно замечание, которое мне не удалось втиснуть в комментарий:

Я видел эту ошибку (пренебрежение списками инициализации), сделанную новичками в C ++, которые пришлииз языков (Java, C #), где все типы являются либо примитивами, либо ссылками.Нет ничего сложного в том, чтобы по умолчанию инициализировать ссылку на сложный тип с null, а затем перезаписать ее реальным объектом.Однако в C ++ типы имеют семантическое значение, если только семантическая ссылка не выбрана явно (и не реализована).

Думайте о том, что T является дорогим для инициализации типом.(Для любого определения «дорого». Если у вас возникли проблемы с представлением такого типа, просто представьте, что мы говорим о коде драйвера графической карты. Почти все дорого для такого кода.) Поскольку вы можете свободно обращаться к объекту втело конструктора должно быть уже построено, когда тело конструктора выполнено.В противном случае вы получите доступ к необработанной памяти вместо действительного объекта.(Конструкция - это то, что превращает блоб необработанной памяти в действительный объект.)

Поэтому, когда вы присваиваете что-то объекту в теле конструктора, вы присваиваете уже полностью построенный объект.Поскольку вы не указали конструктор, объект будет создан с использованием конструктора по умолчанию.Это означает, что объект сначала будет создан по умолчанию, просто чтобы его значение по умолчанию было перезаписано чем-то другим в самый следующий момент.

Это, конечно, глупость, поэтому у нас есть списки инициализации.Используя их, мы можем указать компилятору, какие конструкторы он должен использовать для создания базового класса и дочерних подобъектов.Таким образом, объекты создаются с правильным значением немедленно.

Кроме того, как вы обнаружили, списки инициализации являются единственным способом инициализации определенных элементов данных, а именно константных объектов, ссылок и объектов типов, которые не имеют доступного конструктора по умолчанию.

...