C++ 包含表达式的初始化列表

C++ Initialization list with expressions

本文关键字:初始化 列表 表达式 包含 C++      更新时间:2023-10-16

我刚刚了解到我应该在我的C++构造函数中使用初始化列表而不是赋值。这是我的例子。

**分配示例: **

Class Graph {
private:
int count;
int spacing;
int width;
public:
Graph(int _count, int _spacing, int _chart_width) {
count = _count;
spacing = _spacing;
width = (_chart_width - ((_count - 1) * _spacing)) / _count;
}
};

**初始化列表示例: **

Class Graph {
private:
int count;
int spacing;
int width;
public:
Graph(int _count, int _spacing, int _chart_width) : count(_count), spacing(_spacing), width((_chart_width - ((_count - 1) * _spacing)) / _count) {}
};

如您所见,这看起来非常丑陋。

我的问题是:

  1. 这是使用表达式编写初始化列表构造函数的方法吗?
  2. 有更好的语法吗?如果表达式真的很长并且使初始化列表语法完全不可读怎么办?
  3. 我是否应该编写一个方法来计算width并清理构造函数getWidth()?像width(getWidth(_chart_width)).
  4. 初始化列表语法指示,例如,count(_count)是一个将_count作为输入参数的函数。我是否将初始化列表语法与函数语法混淆了?还是count()真的是一种功能?这是非常令人困惑的。
  5. 如果我编写初始化列表的方式是正确的,您能否建议一种更好的方法来格式化代码以提高可读性?我想,我想知道长初始化列表最常见的语法是什么。

不同的项目(和人)有不同的编码标准和品味,但我个人觉得这种格式非常可读:

Class Graph {
private:
int count;
int spacing;
int width;
public:
Graph(int _count, int _spacing, int _chart_width)
: count(_count), spacing(_spacing),
width((_chart_width - ((_count - 1) * _spacing)) / _count)
{}
};

不,这些不一定是函数调用。但它们可以是...最好的思考方法是:如果要初始化的变量是类的实例,则调用构造函数来初始化它们。如果以这种方式查看,则语法是有意义的。

我会推荐一个辅助函数(作为类的私有和静态方法)来计算宽度。

这是使用表达式编写初始化列表构造函数的方法吗?

是的,它是(尽管您可以将其格式化为更具可读性)。

有更好的语法吗?如果表达式真的很长并且使初始化列表语法完全不可读怎么办?

不是我知道的。如果列表太长,您可以按行设置列表的格式。如果你的参数初始化很长,很复杂,几乎不可读(即需要2-3行并且充满了逻辑),我建议将其移动到构造函数的主体。作为一般经验法则,初始值设定项列表就是用来做到这一点的:初始化。出于以下几个原因,您不应该在列表的参数中执行逻辑块:

如果你的参数
  1. 需要一个小的数学方程,那很好,但除此之外的任何参数都可能需要它自己的函数。也可以在对象的构造函数中完成,您可以在其中使用 names 变量来表示正在发生的事情。

  2. "干净代码"的一般规则是不要试图变得聪明。如果某些内容不可读,您应该积极努力使其被同行理解。

  3. 请参阅下一个问题的答案。

我应该写一个方法来计算宽度并清理构造函数吗?类似于width(getWidth(_chart_width))。

  1. 初始值设定项列表的参数中使用函数调用是完全可以接受的。为了可读性,我什至鼓励你这样做。归根结底,初始值设定项列表的主要功能之一是删除构造函数中可以填充它的"x = _x"行,并为不仅仅是赋值的函数腾出一些空间。

初始化列表语法指示,例如,count(_count) 是一个将_count作为输入参数的函数。我是否将初始化列表语法与函数语法混淆了?还是 count() 真的是一个函数?这是非常令人困惑的。

基本上,C++正在创建一个隐式函数,将传递的参数分配给适当的变量。可以将其视为C++创建一堆不可见的函数,如下所示:

aType setVarName(aType aParam)
{
varName = aParam;
}

如果我编写初始化列表的方式是正确的,您能否建议一种更好的方法来格式化代码以提高可读性?我想,我想知道长初始化列表最常见的语法是什么。

初始值设定项列表应位于定义构造函数的同一位置。在您提供的示例中,构造函数为空,因此您决定在头文件中定义它,以便您也可以在其中定义列表。我知道这不适用于您的情况,但请记住,如果您的构造函数确实有内容,您应该在".cpp"文件中构造函数块的正上方定义列表:

Graph(int _count, int _spacing, int _chart_width) : 
count(_count),
spacing(_spacing), 
width((_chart_width - ((_count - 1) * _spacing)) / _count) 
{
...
[your constructor's code here]
...
}

我被教导应该用新行分隔每个参数,但正如雨城所说:"不同的项目(和人)有不同的编码标准和品味"。

实际上,无论如何,我都建议不要将其全部写在一行中,因为如果它变大,它会严重阻碍其可读性。您通常希望避免需要"纵向监视器"用户必须水平滚动的行。

编辑:我注意到你在另一条评论中说你有java的背景,并且想知道int vs object背后的逻辑。虽然我不确定Java是否这样做,但C++做了很多隐式函数定义,它将"静默地"生成函数来完成一些常见的行为。例如,对象可以有一个隐式复制构造函数,它允许您通过向对象传递另一个相同类型的对象来创建对象的实例。但是,在初始值设定项列表的情况下,它们只是为变量赋值的隐式函数。我建议阅读C++中隐式函数的不同情况,以理解它。

我的问题是:

  1. 这是使用表达式编写初始化列表构造函数的方法吗?

是的

  1. 有更好的语法吗?如果表达式真的很长并且使初始化列表语法完全不可读怎么办?

使用多行,并在行变长时缩进。

  1. 我应该写一个方法来计算宽度并清理构造函数吗?类似于width(getWidth(_chart_width))。

是的,你可以这样做,但它不能是同一类的实例方法,因为你还没有"this"。

    初始化
  1. 列表语法表示,例如,count(_count) 是一个将_count作为输入参数的函数。我是否将初始化列表语法与函数语法混淆了?还是 count() 真的是一个函数?这是非常令人困惑的。

语法相同。 代码中的位置将其标识为初始化而不是函数调用(在构造函数签名后面的":"字符之后)。 不,count 不是一个函数,它只是指示 x(y) 用 y 初始化 x 的一种方式。 在C++中,相同的语法可以用于不同的事情,它们通过周围的上下文来区分。 你会发现 x(y) 语法用于C++中的其他事情(宏是一个,强制转换是另一个,超类初始化是另一个)。

  1. 如果我编写初始化列表的方式是正确的,您能否建议一种更好的方法来格式化代码以提高可读性?我想,我想知道长初始化列表最常见的语法是什么。

只需使用多行即可。 新行可以在任何有空格的地方使用。 使用新行时,使用了其他缩进。 您可以使用一点创造力,也可以参考编码标准文档以获取想法。 这很好:

Graph(int _count, int _spacing, int _chart_width) : 
count(_count), 
spacing(_spacing),
width((_chart_width - (_count - 1) * _spacing) / _count) {}

或者,如果有很多参数,您可以执行以下操作:

Graph(int _count,
int _spacing,
int _chart_width) : 
count(_count), 
spacing(_spacing),
width((_chart_width - (_count - 1) * _spacing) / _count) {}