【问题标题】:Preference on initialising variables in C++在 C++ 中初始化变量的偏好
【发布时间】:2023-04-05 10:21:01
【问题描述】:

从 c++ 开始,发现可以通过两种方式初始化变量

int example_var = 3;  // with the assignment operator '='

int example_var(3);  // enclosing the value with parentheses 

有理由使用其中一个吗?

【问题讨论】:

  • 您知道,如果您在自己的类型上测试它,MyClass obj = 5; 会调用构造函数,而不是赋值运算符。我也知道以前有人问过这个问题;我会试着找到它的去向。
  • 从技术上讲,这些都不是作业。它们是初始化。他们定义并初始化一个新变量。当您将新值分配给现有变量时,就会发生分配。 (int i = 1 是初始化,i = 2 是赋值)

标签: c++ variable-assignment copy-constructor assignment-operator


【解决方案1】:

第一种形式可以追溯到 C 时代,而第二种形式是在 C++ 中添加的。添加的原因是在某些情况下(特别是构造函数中的初始化列表)第一种形式是不允许的。

这两者并不是对所有类型都完全等价的,这就是其中一种可能更有用的地方。第一种形式在语义上意味着从右侧创建临时变量,然后从该临时变量复制构造。第二种形式,是从参数直接初始化变量。

什么时候重要?

如果没有从右侧到变量类型的隐式转换,或者如果复制构造函数不可用,则第一种形式将失败,因此在这些情况下,您将不得不使用直接初始化。

第二种形式比第一种形式可以在更多的上下文中使用,但是它很容易出现最麻烦的解析。也就是说,在某些情况下,语法将与函数的声明(而不是常规变量的定义)兼容,并且语言确定在这种情况下,表达式将被解析为函数声明:

std::string s = std::string();  // ok declares a variable
std::string s( std::string() ); // declares a function: std::string s( std::string(*)() )

最后在 C++11 中还有第三种形式,使用花括号:

std::string s{std::string{}};

这种形式具有带括号直接初始化的优点,但同时也不易产生误解。

使用哪一个?

如果可以的话,我会推荐第三个选项。话虽如此,我倾向于使用第一个,或者第二个,具体取决于上下文和类型......

【讨论】:

    【解决方案2】:

    他们的输出是一样的... 这两种语法都调用复制构造函数。 对于 int 和其他类似的内置数据类型也是如此,尽管用户定义的数据类型存在一些差异。

    【讨论】:

      【解决方案3】:

      对于像int 这样的内置类型,两者的含义相同。
      但对于自定义数据类型,它们可能意味着不同。第一种格式称为复制初始化,第二种称为直接初始化

      好读:

      Is there a difference in C++ between copy initialization and direct initialization?

      【讨论】:

        【解决方案4】:

        它们编译成相同的东西。然而,两者都是变量初始化的一种形式,而不是赋值,这在 C 中很重要,在 C++ 中很重要,因为调用了完全不同的函数(构造函数与赋值)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-11
          • 2015-04-22
          相关资源
          最近更新 更多