2

我需要一个没有参数的默认构造函数。如何初始化a对我来说类型未知的属性。

template <typename Type>
class Foo
{
public:
    Foo() : a(), b(0) {}  <---- Here is the confusion

private:
    Type a;
    int b;
};

编辑:答案已在下面的评论中给出,但仍有一些我不明白的地方。如果我有 :

typedef enum {AB, CD} EnumType

template <typename Type>
class Foo
{
public:
    Foo() {}  // <---- "Member 'b' was no initialized in this constructor"

private:
    Type a;
    EnumType b;
};

我的编译器给了我这个警告:Member 'b' was no initialized in this constructor。为什么它给我这个警告b是 enum 而不是 for a

4

2 回答 2

2

如何初始化我未知类型的属性 a 。

您的解决方案是正确的。根据 C++11 标准的第 8.5/11 段:

初始值设定项为空括号集的对象,即 (),应进行值初始化。[...]

然后,第 8.5/8 段:

对 T 类型的对象进行值初始化意味着:

— 如果 T 是(可能是 cv 限定的)类类型(第 9 条),没有默认构造函数(12.1)或用户提供或删除的默认构造函数,则对象被默认初始化;

— 如果 T 是(可能是 cv 限定的)非联合类类型,没有用户提供或删除的默认构造函数,则该对象为零初始化,如果 T 具有非平凡的默认构造函数,则默认初始化;

— 如果 T 是一个数组类型,那么每个元素都是值初始化的;

— 否则,对象被零初始化。

最后,

为什么它给我这个警告 b 这是一个枚举而不是 a ?

这可能是因为您指定了一个模板参数,Type该参数是一个可以默认构造的 UDT(用户定义类型)。如果不是这种情况,那么我希望编译器也会警告您a未在构造函数中初始化。但是请注意,编译器不需要发出任何此类警告。

于 2013-03-24T21:52:23.363 回答
1

只要类型Type具有默认构造函数,这是正确的。当您声明模板时,您假设了一些关于类型的事情,并非每种类型都可以在特定模板的构造函数中传递。在这里,对于标准类型和具有默认构造函数的类型,一切都很好。如果您Foo使用自己的类型初始化类,该类型不提供默认构造函数,那将是一个错误。

回答你的第二个问题:

如果您在命名空间范围内定义了变量,则它的值将初始化为 0。

enum SomeEnum {  
    EValue1 = 1,  
    EValue2 = 4,  
};
SomeEnum e; // e is 0
int i;      // i is 0

int main()
{
    cout << e << " " << i; //prints 0 0 
}

不要感到惊讶,e它的值可以不同于任何SomeEnum' 的枚举值。每个枚举类型都有一个基础整数类型(例如intshortlong),并且该枚举类型的对象的可能值集是基础整数类型具有的值集。枚举只是一种方便地命名某些值并创建新类型的方法,但您不会通过枚举器的值集来限制枚举的值。

对 T 类型的对象进行零初始化意味着:
— 如果 T 是标量类型 (3.9),则将对象设置为转换为 T 的值 0(零);

请注意,枚举是标量类型。

对 T 类型的对象进行值初始化意味着:
— 如果 T 是类类型 blah blah
— 如果 T 是非联合类类型 blah blah
— 如果 T 是数组类型,则 blah blah — 否则,对象为零-初始化

typedef enum {a,b,c,d} EnumType;

template <typename Type>
class Foo
{
public:
    Foo() {}  // <---- "Member 'b' was no initialized in this constructor"

public:
    Type a;
    EnumType b;
};

/*
 * 
 */
int main(int argc, char** argv) {

    Foo<int> fo;
    std::cout<<std::endl<<"fo.a:"<<fo.a<<",fo.b:"<<fo.b<<std::endl;
    EnumType e=d;
    fo.b=d;
    std::cout<<std::endl<<"fo.a:"<<fo.a<<",fo.b:"<<fo.b<<std::endl;

    Foo<int>* go=new Foo<int>;
    std::cout<<std::endl<<"go->a:"<<go->a<<",go->b:"<<go->b<<std::endl;
    go->b=d;
    std::cout<<std::endl<<"go->a:"<<go->a<<",go->b:"<<go->b<<std::endl;

fo.a:-137090040,fo.b:32767

fo.a:-137090040,fo.b:3

去->a:-166889576,去->b:32767

去->a:-166889576,去->b:3

现在:

    Foo<int>* go=new Foo<int>();
    std::cout<<std::endl<<"go->a:"<<go->a<<",go->b:"<<go->b<<std::endl;
    go->b=d;
    std::cout<<std::endl<<"go->a:"<<go->a<<",go->b:"<<go->b<<std::endl;

去->a:0,去->b:0

去->a:0,去->b:3

于 2013-03-24T21:39:59.187 回答