C++定义构造函数使对象成为非 POD

C++ defining constructor make object non POD

本文关键字:POD 对象 定义 构造函数 C++      更新时间:2023-10-16

如果我有一个简单的结构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"
}

现在想象一下,我想默认启动成员并直接执行以下操作:

struct Foo {
int a;
int b;
bool c = true;
};

结构不再是 POD!即使使用这样的构造函数:

struct Foo {
int a;
int b;
bool c;
Foo() : a(0), b(0), c(false) {}
};

Foo已经失去了它的PODness...

现在棘手的部分开始了。想象一下,我想添加一个构造函数,a

struct Foo {
int a;
int b;
bool c;
Foo(int a) : a(a), b(0), c(false) {}
};

现在Foo绝对不是POD。但是,如果添加默认构造函数:

struct Foo {
int a;
int b;
bool c;
Foo() = default;
Foo(int a) : a(a), b(0), c(false) {}
};

Foo现在是一个POD!

如您所见,即使我只想使用第二个示例中的默认值,我也会丢失 PODness,但只要我定义显式默认构造函数,我就可以重新获得它。

所以问题是:我们是否应该始终添加一个默认构造函数,以便我们可以从类的 PODness 中受益并提高性能?仅仅因为我想默认初始化某些成员而失去性能太糟糕了......

换句话说,像第二个示例中那样定义默认值会使结构非 POD 和不平凡,这在性能方面很糟糕,那么我如何默认初始化值并保持结构简单?一个简单的解决方案是定义一个返回默认初始化 Foo 的initFoo函数,例如:

Foo initFoo() {
Foo foo;
foo.a = 0;
foo.b = 1;
foo.c = true;
return foo;
}

但这还不是很C++,但无论如何,这样做是正确的吗?

我们是否应该始终添加一个默认构造函数,以便我们可以从类的 PODness 中受益

如果您希望一个类是 POD,那么它必须是微不足道的默认可构造的,以及其他要求。

实现该要求的一种方法是不声明任何构造函数或默认成员初始化器。另一种方法是将默认构造函数定义为默认值。如果希望类具有任何非默认构造函数,则后者是唯一的方法。

就PODness 而言,选择哪种方法并不重要。


但这是正确的做法吗?

initFoo是返回具有特定值的Foo的正确方法。就个人而言,我在局部变量中看不到价值,而是会这样做:

return {
0,
1,
true,
};

不幸的是,我们从初始化器中丢失了成员名称,至少在 C++20 之前我们可以编写:

return {
.a = 0,
.b = 1,
.c = true,
};