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'

我认为构造函数用于初始化数据成员。怎么了????

4

2 回答 2

11

您没有初始化 const 成员,您只是分配给它。

成员的初始化只能使用成员初始化列表来完成

例如:

TemplateClass() : constMember(T()) //initializes constMember to 0
{} 
于 2010-09-21T14:29:21.637 回答
4

Prasoon已经给了你一个很好的答案。但是,我想补充一点,我无法挤进评论:

我已经看到这个错误(忽略初始化列表)是 C++ 新手犯的很多错误,这些新手来自所有类型都是基元或引用的语言(Java、C#)。null用一个真实的对象默认初始化一个复杂类型的引用,然后用一个真实的对象覆盖它,这没什么大不了的。然而,在 C++ 中,类型具有值语义,除非明确选择(并实现)引用语义。

想想你T是一个昂贵的初始化类型。(对于“昂贵”的任何定义。如果您无法想象这样的类型,请想象我们正在谈论图形卡驱动程序的代码。对于此类代码来说,几乎任何东西都是昂贵的。)因为您可以自由访问对象构造函数的主体它需要在执行构造函数的主体时已经被构造。否则,您将访问原始内存而不是有效对象。(构造是将一块原始内存变成有效对象的过程。)

因此,当您将某些内容分配给构造函数主体中的对象时,您正在分配给已经完全构造的对象。由于您没有指定构造函数,因此将使用其默认构造函数构造对象。这意味着对象将首先被默认构造,只是为了在下一刻用其他东西覆盖它的默认值。

这当然是胡说八道,这就是我们有初始化列表的原因。使用它们,我们可以向编译器指定它应该使用哪些构造函数来构造基类和成员子对象。这样,对象会立即以正确的值创建。

此外,正如您所发现的,初始化列表是初始化某些数据成员(即常量对象、引用和没有可访问的默认构造函数的类型的对象)的唯一方法。

于 2010-09-21T19:06:00.793 回答