带表达式的C ++初始化列表

时间:2018-01-29 00:22:53

标签: c++ syntax constructor code-formatting initialization-list

我刚刚得知我应该在我的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. 我应该编写一个计算getWidth()的方法width并清理构造函数吗?像width(getWidth(_chart_width))
  4. 之类的东西
  5. 初始化列表语法表示,例如,count(_count)是一个将_count作为输入参数的函数。我是否将初始化列表语法与函数语法混合在一起?或count()真正的功能?这非常令人困惑。
  6. 如果我编写初始化列表的方式是正确的,您能否建议一种更好的方法来格式化代码以便于阅读?我想,我想知道长初始化列表最常用的语法是什么。

3 个答案:

答案 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行并且充满逻辑),我建议将它移动到构造函数的主体。作为一般经验法则,初始化列表用于执行以下操作:初始化。由于以下几个原因,您不应该在列表的参数中执行逻辑块:

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

  2. “清洁代码”的一般规则是不要试图变得聪明。如果某些内容不可读,您应该积极努力让同行理解它。

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

  4.   

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

    1. 在初始化列表的参数中使用函数调用是完全可以接受的。为了便于阅读,我甚至鼓励你这样做。在一天结束时,初始化程序列表的主要功能之一是清除构造函数中可填充它的“x = _x”行,并为不仅仅指定值的函数腾出一些空间。
    2.   

      初始化列表语法表示,例如,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)

我的问题是:

  1. 这是用表达式编写初始化列表构造函数的方法吗?
    1. 有更好的语法吗?如果表达式很长并且初始化列表语法完全不可读怎么办?
    2. 当行变长时使用多行和缩进。

      1. 我应该编写一个方法getWidth()来计算宽度并清理构造函数吗?类似宽度(getWidth(_chart_width))。
      2. 是的,你可以这样做,但它不能是同一个类的实例方法,因为你没有"这个"爱好。

        1. 初始化列表语法表示,例如,count(_count)是一个将_count作为输入参数的函数。我是否将初始化列表语法与函数语法混合在一起?或者count()真的是一个函数?这非常令人困惑。
        2. 语法是一样的。它是代码中的位置,将其标识为初始化而不是函数调用(遵循构造函数签名后的':'字符)。不,count不是函数,它只是一种指示x(y)用y初始化x的方法。在C ++中,相同的语法可以用于不同的事物,它们由它们周围的上下文区分。您会发现x(y)语法用于C ++中的其他内容(宏是一个,强制转换是另一个,超类初始化是另一个)。

          1. 如果我编写初始化列表的方式是正确的,您能否建议一种更好的方法来格式化代码以便于阅读?我想,我想知道长初始化列表最常用的语法是什么。
          2. 只需使用多条线。只要有空位,新线就可以使用。当您使用新行时,使用其他缩进。您可以使用一点创造力,或者您可以参考编码标准文档的想法。这很好:

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

            或者如果参数很多,你可以这样做:

            {{1}}