2010-09-21 5 views
0

Мой код не компилируется. Ниже мой кодПроблемы с инициализацией элемента класса шаблона

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'

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

+1

@ user242265: Ваша проблема не имеет ничего общего с шаблонами, кстати. – wilx

ответ

11

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

Инициализация членов can only be done using a member initialization list.

Например:

TemplateClass() : constMember(T()) //initializes constMember to 0 
{} 
+0

Я бы сказал, что «может только», а не должен. «Инициализация членов может быть выполнена только с помощью списка инициализации члена». – frag

+1

@frag: Верно, отредактировал мой ответ. –

+0

Хороший ответ, '+ 1' от меня. Однако я почувствовал необходимость провести еще несколько слов по этому вопросу. ':)' – sbi

4

Prasoon уже дал вам a very good answer. Тем не менее, я хотел бы добавить дополнительную информацию, которую я не мог сжать в комментарий:

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

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

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

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

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

Смежные вопросы