结构中的默认成员值或默认构造函数参数?

马修

在现代C ++中,我被允许使用默认成员值来实现结构,即

struct A
{
  int x = 5;
  float y = 1.0f;
};

但我也可以创建一个没有“默认成员值”的结构,但可以使用默认参数调用其构造函数,如以下示例所示:

struct B {
  int x;
  float y;

  B(int x_ = 5, float y_ = 1.0f) : x(x_), y(y_) {}
};

我想知道的是,从干净的代码或体系结构的角度来看,它们之间是否有区别?也许还有另一个甚至更重要的差异?在第一种情况下,我要编写的代码量更少,并且我相信A({2, 3.14f})即使没有定义构造函数,我仍然可以像构造对象一样构造对象

您将在项目中采用哪种方式,为什么?

润滑脂

没有“正确”的方法来选择初始化形式,它取决于项目的特定约束/情况,甚至取决于您的个人喜好。但是,我认为在确定Pro / Contra类内初始化程序时应考虑这些问题。

  1. 优点:可读性。当您想了解类的优点时,通常会从其定义开始。遍历数据成员时,让您的大脑舒适地将每个数据成员的初始值放在其类型旁边,而不用扫描可能的多个构造函数。

  2. Pro:无需复制粘贴其他现有构造函数的初始化程序时,添加更多构造函数就容易得多。使用类内成员初始化器,添加构造函数时,您不太可能会忘记一些初始化。

  3. Pro:删除构造函数很容易。假设您从一个新类开始,添加了一堆成员函数,一个构造函数和数据成员。然后,您还记得Scott Meyers在“非成员函数如何改善封装”中所说的内容,并决定将成员函数转换为自由函数。现在,您的类型看起来像是一个愚蠢的东西struct,其中包含一些数据,当它的构造函数不涉及任何业务逻辑时,您可能希望将其转换为聚合:使用类初始化程序时,您只需删除构造函数即可。

  4. 相反:每当在类初始化程序中使用时,必须知道要初始化的数据成员的具体类型。当相关的类定义在标头中(最可能),编译时间是一个问题(最可能),相关的数据成员具有较重的定义(有时)和/或需要非对构造的琐碎依赖(有时)。一个简单的指导原则可能是:在Pimpl习惯用法很有用的情况下,它比1.-3点更为重要。并且确实排除了类内的初始值设定项,因此请选择Pimpl。

最后说明:核心指南建议在C.48中使用类内初始化程序,其理由如下:

明确指出所有构造函数都应使用相同的值。避免重复。避免维护问题。它导致最短和最有效的代码。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

C++ 默认成员初始化和构造函数

C ++ c-tor处理默认成员值构造异常?

C ++ 11,默认成员构造是件好事吗?

普通的默认构造函数在这里应该尊重默认成员初始化程序吗?

是否可以在默认成员初始化程序中调用非静态成员函数?

C ++构造函数中参数的默认值

公共班级的默认成员

默认成员值和不完整类型的模板扩展中的编译器差异

C ++ 11:使用非静态成员函数作为类构造函数中的默认参数

移动构造函数中的默认参数

“成员函数外部的封闭类定义中需要默认成员初始化程序”-我的代码格式错误吗?

C ++结构默认构造函数

构造函数链接不使用类成员的默认值?

这会更改默认和非默认构造函数中的值

如何在继承层次结构中调用具有默认参数的构造函数?

使用反射获取超载的默认成员

IcCube-忽略默认成员

具有默认值的单参数构造函数与默认构造函数相同吗?

未使用的默认成员初始值设定项如何改变 C++ 中的程序行为?

Swift:使用成员常量作为函数参数的默认值

在 C++ struct 中,构造函数中的默认值和默认参数有什么区别?

迅捷-我可以从自定义init方法调用结构默认成员级init吗?

具有类成员默认值的C ++ 11默认构造函数行为

为什么 Typescript 类中的箭头类成员函数无法识别参数属性的默认值?

构造函数中定义的类函数的默认参数

使用默认参数而不是默认构造函数调用构造函数

构造函数默认列表值

如何使用函数成员和默认公共构造函数创建 F# 结构?

Scala:如何在伴随对象中定义构造函数参数的默认值?