【问题标题】:C++ defining constructor make object non PODC++定义构造函数使对象非POD
【发布时间】:2020-06-08 20:34:56
【问题描述】:

如果我有一个简单的结构 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 已经失去了它的 POD...

现在棘手的部分开始了。想象一下,我想添加一个采用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!

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

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

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

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

但这不是非常 C++,但无论如何它是正确的做法吗?

【问题讨论】:

  • POD 必须满足许多要求。拥有一个简单的默认构造函数并不会自动使其成为 POD。在大多数情况下,structclass
  • 为什么你认为类是 POD 会提高性能?即便如此:性能,什么操作,究竟是什么?您是否对您的代码进行了分析,以确保将您的类作为 POD,在您使用它们的任何用例中都能带来更好的性能?
  • 请注意 std::is_pod 现在(以及在实际发布 C++20 时)已弃用。 PODness 是一个正在被移除的概念。
  • @Ron 当然我认为结构的其余部分是符合 POD 的,这里我只是在谈论具有默认值。
  • 一个可能的答案是:不,你不应该总是为你的类添加一个默认构造函数,假设你会从 POD-nes 和性能中受益。

标签: c++ default-constructor


【解决方案1】:

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

如果你想让一个类成为 POD,那么它必须是默认可构造的,以及其他要求。

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

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


但是这样做是正确的吗?

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

return {
    0,
    1,
    true,
};

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-16
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多