C++ 默认参数与初始器列表

c++ default argument vs. initalizer list

本文关键字:列表 默认 参数 C++      更新时间:2023-10-16

有四种特定情况,您必须指定默认的初始值设定项列表。在这里充分讨论

简而言之,如果你有

初始值设定项列表 必需

  1. 非静态常量数据成员
  2. 引用类型的数据成员
  3. 为作为其他类对象的数据成员提供参数
  4. 提供派生类中的基类 CTOR 参数。
默认参数

的一个缺点似乎是默认参数必须是函数原型参数列表中的尾随参数。例如:

默认参数的缺点(???)

void f(int, int = 2, int = 3);     // trailing defaults
void g(int = 1, int = 2, int c);   // error
void h(int, int = 3, int);         // error

我的问题是,如果我的代码不在初始化程序列表的 4 种必需情况之间,并且始终要求所有参数都具有默认值,即不会导致默认参数的缺点,我应该选择哪一个,为什么?最佳实践是什么?

一个例子是

// option -1: for the default argument list
// my_array.h
my_array(int a_number_of_elements = 0, int default_val = 0);
//option-2 : default initalizer list
// my_array.h
my_array(int a_number_of_elements, int default_val);
//my_array.cpp
my_array:: my_array(int a_number_of_elements, int default_val)
                   : my_num_elements(a_num_elements), my_default_value(default_val)

谢谢你的关注。

您在这里处理的是两件完全不同的事情:构造函数初始值设定项列表默认函数参数

您正确理解了大部分内容,但与您可能认为的相反,默认构造函数参数并不意味着使用这些值构造数据成员,除非您明确声明。因此,一种技术不能替代另一种技术,只是分开互补的东西。

例如:

// my_array.h
my_array(int a_number_of_elements = 1, int default_val = 0);
//my_array.cpp
my_array:: my_array(int a_number_of_elements, int default_val)
                   : my_num_elements(a_num_elements), my_default_value(default_val)

将 [预期] 使用一个值为零的元素初始化数组。

如果未显式调用数据成员的构造函数,则将调用其默认构造函数(如果可用),因此以下两个是等效的。

//implicitly default constructing members
my_array:: my_array()
{}
//explicitly default constructing members
my_array:: my_array() :
    my_num_elements(), my_default_value()
{}

关于上述两个,为了更好的易读性,将内容明确始终是一个好主意。正如常说的,给定的代码通常写一次,但读取多次。

你在这里有几个误解:

  1. 您指的是"构造函数初始值设定项列表"initializer_list
  2. 您似乎认为默认参数只能与"构造函数初始化列表"分开使用

让我们在这里谈谈一些原则:

  • 始终希望对所有变量使用"构造函数初始值设定项列表",而不仅仅是您提到的 4 种类型的变量。"构造函数初始值设定项列表"值初始化,而不是默认初始化并要求您在构造函数主体中分配给它们
  • 在可能的情况下,您将始终希望有一个默认构造函数,因为在标准容器中使用对象时,这是必需
  • 的默认
  • 参数是防止用户定义构造函数和用户定义默认构造函数的代码重复的好方法

因此,使用这些原则,我可以说您的问题的答案是肯定的,理想的情况是同时使用"构造函数初始值设定项列表"和默认参数。生成如下所示的构造函数:

my_array(int a_number_of_elements = 0, int default_val = 0) :
    my_num_elements(a_number_of_elements),
    my_default_value(default_val) {}