我刚刚得知我应该在我的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) {}
};
如您所见,这看起来很丑陋。
我的问题是:
getWidth()
的方法width
并清理构造函数吗?像width(getWidth(_chart_width))
。count(_count)
是一个将_count
作为输入参数的函数。我是否将初始化列表语法与函数语法混合在一起?或count()
真正的功能?这非常令人困惑。答案 0 :(得分:2)
不同的项目(和人)有不同的编码标准和口味,但我个人认为这种格式非常易读:
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 :(得分:0)
这是用表达式编写初始化列表构造函数的方法吗?
是的,它是(虽然您可以将其格式化为更易读)。
有更好的语法吗?如果表达式非常长并且初始化列表语法完全不可读怎么办?
不是我知道的。如果列表变得太长,您可以将列表格式化为行。如果参数的初始化很长,很复杂且几乎不可读(即需要2-3行并且充满逻辑),我建议将它移动到构造函数的主体。作为一般经验法则,初始化列表用于执行以下操作:初始化。由于以下几个原因,您不应该在列表的参数中执行逻辑块:
如果你的参数需要一个小的数学方程式,那很好,但除此之外的任何东西都可能需要它自己的函数。它也可以在对象的构造函数中完成,您可以使用名称变量来表示正在发生的事情。
“清洁代码”的一般规则是不要试图变得聪明。如果某些内容不可读,您应该积极努力让同行理解它。
请参阅下一个问题的答案。
我应该编写一个方法getWidth()来计算宽度并清理构造函数吗?类似宽度(getWidth(_chart_width))。
初始化列表语法表示,例如,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对象背后的逻辑。虽然我不确定Java是否这样做,但C ++做了很多隐式函数定义,它会“静默地”生成函数来完成一些常见的行为。例如,对象可以有一个隐式复制构造函数,它允许您通过传递另一个相同类型的对象来创建对象的实例。但是,在初始化列表的情况下,它们只是为变量赋值的隐式函数。我建议您阅读C ++中隐式函数的不同情况,以了解它。
答案 2 :(得分:0)
我的问题是:
是
当行变长时使用多行和缩进。
是的,你可以这样做,但它不能是同一个类的实例方法,因为你没有"这个"爱好。
语法是一样的。它是代码中的位置,将其标识为初始化而不是函数调用(遵循构造函数签名后的':'字符)。不,count不是函数,它只是一种指示x(y)用y初始化x的方法。在C ++中,相同的语法可以用于不同的事物,它们由它们周围的上下文区分。您会发现x(y)语法用于C ++中的其他内容(宏是一个,强制转换是另一个,超类初始化是另一个)。
只需使用多条线。只要有空位,新线就可以使用。当您使用新行时,使用其他缩进。您可以使用一点创造力,或者您可以参考编码标准文档的想法。这很好:
Graph(int _count,
int _spacing,
int _chart_width) :
count(_count),
spacing(_spacing),
width((_chart_width - (_count - 1) * _spacing) / _count) {}
或者如果参数很多,你可以这样做:
{{1}}