情况如下:
我有一个由以下文件定义的类。
Foo.h文件:
template<typename MyType>
class Foo
{
public:
Foo(int number = 50);
private:
typedef enum {VAR1, VAR2} Type;
class Bar
{
MyType a;
Type b;
Bar(int param1, Type param2) : a(param1), b(param2) {}
}
std::vector<Bar> vec;
};
Foo.cpp文件:
template<typename MyType>
Foo::Foo(int number) : vec(number)
{ }
问题是当我编译它时,我在.cpp文件的第一行中收到错误,说它需要一个没有参数的Bar的构造函数。我想它需要它在Foo中创建矢量。我为Bar添加了一个没有参数的构造函数,给出了以下.h文件:
template<typename MyType>
class Foo
{
public:
Foo(int number = 50);
private:
typedef enum {VAR1, VAR2} Type;
class Bar
{
MyType a;
Type b;
Bar() {} // <---- Line added
Bar(int param1, Type param2) : a(param1), b(param2) {}
}
std::vector<Bar> vec;
};
现在我可以编译并且它可以正常工作,但是我刚刚添加的一行警告Member 'b' was no initialized in this constructor
。枚举问题,也许?
我不明白我应该怎么做才能让它在没有这个警告的情况下工作。
编辑:我收到了一些答案,说要向空构造函数添加初始化列表。但是,我的类实际上是一个模板类,a
对我来说是一个未知的类型,所以我不能初始化它,因为我不知道它的类型。我尝试在Bar的初始化列表中仅初始化b
并且它有效。警告消失了,但让a
未初始化是否可以?是否有一种方法可以删除没有Bar参数的构造函数,并且仍然在Foo的构造函数中给出向量的大小?
答案 0 :(得分:6)
问题是Foo::Foo(int)
定义中的初始化列表。你在写
Foo::Foo(int n)
: vec(n) { }
即。你正在使用构造函数
std::vector<Bar>::vector(size_t number, const Bar &x = Bar())
请注意x = Bar()
,这意味着您使用标准构造的Bar
实例填充向量。由于Bar
中至少定义了一个构造函数,编译器不会自动提供标准构造函数。
在Bar
中定义一个标准构造函数,就像其他答案一样,或者在Foo
的构造函数中添加其他内容,例如
Foo::Foo(int n)
: vec(n, Bar(1, VAR1)) { }
并且编译器错误消失。
回答您的修改:您收到的警告可能表示:成员a
未正确初始化。因为它是int
这可能没问题(C ++不会强迫你初始化int
)。但请注意程序中稍后成员a
中的奇怪和任意值。一个更好的解决方案是将它在施工时设置为一个良好的定义状态,这意味着“这个值是未知的。”
编辑:我删除了我写的有关异构容器的所有内容。但是,如果您需要这些内容,请查看我的帖子的编辑历史记录。
您可以在a
的标准构造函数中初始化Bar
,如下所示:
Bar::Bar() : a(MyType()), b(UNKNOWN) { }
并将UNKNOWN
添加到枚举Type
。这假设类型MyType
是标准可构造的。这适用于所有原始类型,例如int
,double
等。这为您提供了一个明确定义的Bar
对象状态,这可能对您意味着 unknown 。可以通过将b
与UNKNOWN
进行比较来测试它。
正如yakk在他的评论中所述:枚举的原始类型可以保留为单元化,但在您的情况下,编译器会警告您:可能是您的成员b
包含的值没有像VAR1
这样的标签或者VAR2
。使用明确定义的值初始化所有成员总是一个好主意,除非你真的被迫不这样做 - 例如,如果执行是血腥的关键。
答案 1 :(得分:0)
您需要向空构造函数添加初始化列表(并可能将其公开)。
class Bar
{
int a;
Type b;
Bar() : a(0), b(VAR1) {} // initialize the members to default values.
Bar(int param1, Type param2) : a(param1), b(param2) {}
}