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

标签 c++ oop c++11 data-structures software-design

在现代 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}) 这样的对象。

您在项目中会采取哪种方式?为什么?

最佳答案

选择初始化形式没有“正确”的方法,这取决于项目的具体限制/情况,甚至您个人的喜好。但是,我认为在决定赞成/反对类内初始化程序时应该考虑这些问题。

  1. 专业:可读性。当您想了解类的用途时,通常会从其定义开始。在浏览数据成员时,您的大脑可以很舒服地将每个数据成员的初始值放在其类型旁边,而不是扫描可能的多个构造函数。

  2. 优点:当不需要复制粘贴另一个现有构造函数的初始值设定项时,添加更多构造函数会容易得多。使用类内成员初始值设定项,您在添加构造函数时不太可能忘记某些初始化。

  3. 优点:删除构造函数很容易。假设您从一个新类开始,添加了一堆成员函数、构造函数和数据成员。然后你想起了 Scott Meyers 在“非成员函数如何改进封装”中所说的话,你决定将成员函数变成自由函数。您的类型现在看起来像一个愚蠢的struct,其中一些数据打包在一起 - 当其构造函数不涉及任何业务逻辑时,您可能希望将该类型转换为聚合:使用类初始值设定项,您可以只需删除构造函数 - 完成。

  4. 相反:每当您使用类初始化器时,必须知道正在初始化的数据成员的具体类型。当所讨论的类定义位于 header 中(最有可能)、编译时间是一个问题(最有可能)、所讨论的数据成员具有重量级定义(有时)和/或需要非对构造的微不足道的依赖(有时)。一个简单的指导原则可能是:在 Pimpl 习惯用法有帮助的情况下,它比第 1.-3 点更重要。并且排除了类内初始化器,所以就使用 Pimpl 吧。

最后一点:核心指南建议在C.48中使用类内初始化器。 ,推理如下:

Makes it explicit that the same value is expected to be used in all constructors. Avoids repetition. Avoids maintenance problems. It leads to the shortest and most efficient code.

关于c++ - 结构中的默认成员值或默认构造函数参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58553525/

相关文章:

javascript - 等到 $http 完成才能在 AngularJS 中输出结果

c++ - Iceberg 类和 Google 单元测试

javascript - 用于标记私有(private)成员的前导下划线

c++ - 在 C++ 中的共享库 (so) 中的共享内存中创建对象

java - BlueJ错误: Incompatible types: int cannot be converted to java. lang.String(票机模拟)

c++ - 将缓冲区对齐到 N 字节边界而不是 2N 字节边界?

c++ - 从类调用函数时箭头 '->' 分隔符崩溃

C++11 线程可连接但 join() 引发异常

c++ - 拾色轮

c++ - Unix IPC 套接字发送/接收同步