当前位置: 首页 > 知识库问答 >
问题:

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

方建明
2023-03-14

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

结构不再是吊舱!即使有这样的构造函数

struct Foo {
  int a;
  int b;
  bool c;

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

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

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

struct Foo {
  int a;
  int b;
  bool c;

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

现在,傅绝对不是一个豆荚。但如果添加默认构造函数:

struct Foo {
  int a;
  int b;
  bool c;

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

福现在是一个豆荚!

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

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

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

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

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

共有1个答案

韶浩博
2023-03-14

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

如果你想让一个类成为POD,那么除了其他要求外,它必须是可构造的。

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

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

但不管怎样,这是正确的做法吗?

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

return {
    0,
    1,
    true,
};

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

return {
    .a = 0,
    .b = 1,
    .c = true,
};
 类似资料:
  • 我试图让类circle扩展Shape类,但JUnit不断出错,说构造函数圆(Point,int)未定义,我如何定义圆构造函数与公共圆(Point[]center,int aradius)不同? 圆圈Java语言

  • 类 类是对某一事物的抽象描述,具体地讲,类是C++中的一种构造的数据类型。它即可包含描述事物的数据,又可包含处理这些数据的函数,类在程序运行时是被用作样板来建立对象的。所以要建立对象,首先必须定义类。 定义类 定义一个类的一般格式为: class 类名{     private:         成员表1;     public:         成员表2;     protected:     

  • 在.citydoor.imports.catalog.tools中打包;

  • 问题内容: 我已经加载了内容模块,我得到的具体错误是: 有什么想法吗?我是从以下教程中获得的:http : //developer.android.com/guide/topics/ui/notifiers/notifications.html 问题答案: 更改此: 至 发生错误是因为在这种情况下,它引用的实例,但构造函数需要一个。您必须传递的上下文是对活动本身的引用,因此您必须使用显式访问它。

  • 问题内容: 好的,我正在做学校的作业,我设置了我的主班和另一个名为“交易”的班。在我的主班我有: 带下划线的交易:表示构造函数未定义。为什么?! Transaction类如下所示: 看起来它应该可以工作,但事实并非如此。即使当我在main中创建新Transaction对象的位置插入一堆变量时,它仍然显示未定义。有人请帮忙! 问题答案: 您的类中没有默认的构造函数定义。 当您提供至少一个参数化构造函

  • 已经给出了所有的DTO@data、@noargsconstructor、@allargsconstructor,所以理想情况下所有的构造函数都应该可用。 我已经尝试用新旧版本的Spring tool suite和更改的lombok jar来构建这个项目。但同样或不同的错误仍在出现。 用STS4和STS 3.9.7尝试,3.9.8同样的问题即将到来。尝试龙目岛1.16.22、1.18.0、1.18.