只要类型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
' 的枚举值。每个枚举类型都有一个基础整数类型(例如int
、short
或long
),并且该枚举类型的对象的可能值集是基础整数类型具有的值集。枚举只是一种方便地命名某些值并创建新类型的方法,但您不会通过枚举器的值集来限制枚举的值。
对 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