如果我有一个简单的结构 Foo
,这样定义,就是一个POD。
#include <iostream>
#include <type_traits>
struct Foo {
int a;
int b;
bool c;
};
int main() {
std::cout << (std::is_pod<Foo>::value ? "POD" : "NON POD") << '\n'; // Prints "POD"
}
现在想象一下,我想默认初始化成员,然后直接这样做,这结构就不再是POD了!
struct Foo {
int a;
int b;
bool c = true;
};
这个结构就不再是一个POD了!即使有了这样的构造函数,Foo也失去了它的POD性..:
struct Foo {
int a;
int b;
bool c;
Foo() : a(0), b(0), c(false) {}
};
Foo已经失去了它的POD性... ...
现在,棘手的部分开始了。想象一下,我想添加一个构造函数,在结构体上取一个 "POD"。a
:
struct Foo {
int a;
int b;
bool c;
Foo(int a) : a(a), b(0), c(false) {}
};
现在Foo绝对不是一个POD。但是,如果添加一个默认的构造函数,Foo现在是一个POD了。
struct Foo {
int a;
int b;
bool c;
Foo() = default;
Foo(int a) : a(a), b(0), c(false) {}
};
Foo就变成了一个POD!
所以正如你所看到的,即使我只是想使用一个默认值,就像第二个例子一样,我失去了POD性,但只要我定义一个显式的默认构造函数,我就可以重新获得它。
所以问题是:我们是否应该总是添加一个默认构造函数,这样我们就可以从类的POD性中获益,提高性能?如果因为我想默认初始化一些成员而损失性能,那就太糟糕了......
换句话说,像第二个例子那样定义默认值会使结构变得非POD和非琐碎,从性能上来说是很糟糕的,那么我怎样才能默认初始化值并保持结构的琐碎呢?一个简单的解决方案就是定义一个 initFoo
函数,返回一个默认初始化的Foo,比如说。
Foo initFoo() {
Foo foo;
foo.a = 0;
foo.b = 1;
foo.c = true;
return foo;
}
但这不是很C++,但无论如何,这样做对吗?
我们是否应该总是添加一个默认的构造函数,这样我们就可以从类的POD性中获益。
如果你想让一个类成为POD,那么除了其他要求外,它必须是可默认构造的。
实现这个要求的一种方法是不声明任何构造函数,也不声明默认成员初始化器。另一种方法是将默认构造函数定义为默认。如果你希望类有任何非默认构造函数,后一种方法是唯一的方法。
就POD性而言,你选择哪种方法并不重要。
但无论如何,这样做是正确的吗?
你的 initFoo
是一种正确的返回方式 Foo
与特定的值。就个人而言,我不认为局部变量有价值,而会这样做。
return {
0,
1,
true,
};
不幸的是,我们失去了初始化器中的成员名称, 至少在C++20之前,我们可以写:
return {
.a = 0,
.b = 1,
.c = true,
};