【问题标题】:question on c++ object construction and scope关于 c++ 对象构造和范围的问题
【发布时间】:2020-12-22 05:38:59
【问题描述】:

这个有点难用语言,这里是sn-p,

int main() {
    int i = 5;
    {
        int i(i);
        i = i+5;
//        int i = i;
//        i = i + 5;

        cout << "inner scope" << endl;
        cout << i << endl;
    }
    cout << "outer scope" << endl;
    cout << i << endl;
}

这给出了正确的输出

inner scope
10
outer scope
5

但如果我这样做,

int main() {
    int i = 5;
    {
      //int i(i);
      //i = i+5;
        int i = i;
        i = i + 5;

        cout << "inner scope" << endl;
        cout << i << endl;
    }
    cout << "outer scope" << endl;
    cout << i << endl;
}

这会引发运行时异常,并给出错误的输出,

inner scope
-858993455
outer scope
5

我感觉这似乎与复制构造函数和赋值构造函数调用顺序的不同有关,但我不太确定,请赐教。

【问题讨论】:

  • 第二个我得到warning: 'i' is used uninitialized [-Wuninitialized]。
  • Wildgues(可能是错误的)是因为事物的顺序。在int i(i) 中,您使用存在于内部循环中的外部 i 来构造一个新的 i。在int i=i中你首先创建了一个变量i,然后尝试将它分配给i,这显然不是外部i,因为内部已经定义了。
  • Gcc(和 clang)对这两种情况都给出 uninitialized 警告。
  • @songyuanyao 你没有为外部作用域初始化j,但是这个点仍然有效。
  • @tesla1060 我想这是UB,一切皆有可能。那么我们就不能说这是一个bug,编译器可以为所欲为。

标签: c++ constructor scope


【解决方案1】:

当你隐藏一个变量时,你会在该范围内删除它的所有痕迹,所以:

int i = i;

这声明i 等于它的(未初始化的)自我。这个变量完全独立于父作用域的i。这实际上是未定义的行为。

奇怪的是,int i(i) 方法使用父作用域的i 进行初始化,尽管它的工作原理相当奇特。但它可能不是定义的行为。

如果您需要以某种方式关联这两个变量,您应该使用不同的变量名。如果没有相互依赖,你可以影子。

换句话说:

int j = i;

【讨论】:

  • int i(i); 与 int i = i; 相同。两者都是UB。
猜你喜欢
  • 2013-01-29
  • 2013-06-07
  • 2011-01-11
  • 2011-10-30
  • 2022-12-28
  • 2021-02-27
  • 1970-01-01
  • 1970-01-01
  • 2014-11-14
相关资源
最近更新 更多