模板类中的默认构造函数,其属性类型未知

时间:2013-03-24 21:33:44

标签: c++ templates initialization-list

我需要一个没有参数的默认构造函数。如何初始化属于我的未知类型的属性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这个警告,这是一个枚举,而不是a

2 个答案:

答案 0 :(得分:2)

  

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

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

  

一个对象,其初始化程序是一组空的括号,即(),应进行值初始化。 [...]

然后,第8.5 / 8段:

  

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

     

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

     

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

     

- 如果T是数组类型,则每个元素都是值初始化的;

     

- 否则,该对象为零初始化。

最后,

  

为什么它给了我这个警告b这是一个enum而不是一个?

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

答案 1 :(得分: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),则将对象设置为值0   (零)转换为T;

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

  

对T类型的对象进行值初始化意味着:
- 如果T是类类型   blah blah
- 如果T是非工会阶级   输入等等等等    - 如果T是数组类型,那么等等等等 -   否则,该对象为零初始化

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

     

中间人&gt;一种:-166889576,中间人&GT; B:32767

     

中间人&gt;一种:-166889576,中间人&GT; 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;
  

中间人&gt;一种:0,中间人&GT; B:0

     

中间人&gt;一种:0,中间人&GT; B:3