成员变量的默认初始化或添加更多构造函数?创建类的最佳实践?

问题描述

遵循关于 learncpp.com 的教程,该教程讨论了在构造函数之外声明成员变量。然而在之前的课程中,作者提到最小化构造函数数量是最佳的,可以通过在构造函数的参数中使用认值来完成。这让我很困惑,因为突然有两个地方可以提供认值,直接在您定义成员变量的地方,以及在构造函数的参数中。此外,似乎在构造函数之外定义认值的全部意义在于防止冗余代码,因为“如果您更新成员的认值,则需要接触每个构造函数”。

这是使用的示例:

class Ball
{
  private:
    std::string m_color{ "black" }; //default value "black" declared here
    double m_radius{};
 
  public:
    Ball(double radius)
        : m_radius{ radius } {}
 
    Ball(const std::string& color = "black",double radius = 10.0) //and here!
        : m_color{ color },m_radius{ radius } {}
 
    void print()
    {
        std::cout << "color: " << m_color << ",radius: " << m_radius << '\n';
    }
};

本教程给出的解决方案似乎在两个地方使用了“黑色”,这与将所有认值放在一个地方以尽量减少构造函数更改的想法相矛盾。我想知道这里的最佳实践是什么,以及是否有更好的方法来编写这个类。

解决方法

您可以通过添加一些构造函数来重写构造函数以使其没有任何默认参数

std::string m_color{ "black" };
double m_radius{10.};  // specify default value here,exactly like color
 
public:

Ball() = default;  // add a default constructor
    
Ball(double radius)   // keep the constructor taking a double
    : m_radius{ radius } {}
 
Ball(const std::string& color)  // add a constructor taking only a string
    : m_color{ color } {}

Ball(const std::string& color,double radius)  // don't provide defaults for the
        : m_color{ color },// 2 argument constructor
          m_radius{ radius } {}

构造函数的这些重载等同于您的版本,并且默认值仅指定一次。