Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在结果中看不到析构函数更改的全局变量_C++ - Fatal编程技术网

C++ 在结果中看不到析构函数更改的全局变量

C++ 在结果中看不到析构函数更改的全局变量,c++,C++,我在一个网站上看到了以下程序,我无法理解其输出。 现在i是一个全局变量,在调用返回main之前,销毁a应该将其更改为10。有人建议,在调用返回main之后会发生A的销毁,但是作为调用方,当我调用函数时,我总是希望结果是最终的。这里函数返回值不是10而是3 我的问题是,为什么我会看到这一点,破坏到底是在哪里发生的。评估的顺序不是你所期望的。调用函数时,函数的参数可以按任意顺序求值,甚至可以交错。所以如果你打电话 f( g(), h(), i() ); 调用g()、h()和i()的顺序由编译器决

我在一个网站上看到了以下程序,我无法理解其输出。

现在i是一个全局变量,在调用返回main之前,销毁a应该将其更改为10。有人建议,在调用返回main之后会发生A的销毁,但是作为调用方,当我调用函数时,我总是希望结果是最终的。这里函数返回值不是10而是3


我的问题是,为什么我会看到这一点,破坏到底是在哪里发生的。

评估的顺序不是你所期望的。调用函数时,函数的参数可以按任意顺序求值,甚至可以交错。所以如果你打电话

f( g(), h(), i() );
调用
g()
h()
i()
的顺序由编译器决定。这也适用于运营商。当你有一个表达式的形式

expr1 << expr2 << expr3 << expr4;

expr1析构函数在对
return
语句中的表达式求值后运行。如果是另一种情况,你会陷入困境:

std::string f() {
std::string res = "abcd";
return res;
}
此函数应返回包含
“abcd”
的字符串对象,而不是已销毁的字符串对象的副本

为什么我看到了这一点,破坏到底在哪里被称为

我相信当实例超出范围时会调用实例析构函数。您可以通过以下方式对其进行测试(通过控制实例的范围——请参见下面的bar())

注意-为了减少混淆,1)重命名全局,2)当foo或bar被称为w.r.t.后继cout时显式控制

int g; // uninitialized!

class A
{
public:
   ~A()
      {
         g=10;
      }
};

int foo()
{
   g=3;
   A ob;
   return g;
} // <<<<<<<<<<< ob destructor called here

int bar()
{
   g=3;
   {
      A ob;
   }  // <<<<<<<<<<< ob destructor called here
   return g;
}

int t272(void)
{
   g = 0;  // force to 0
   std::cout << "\n 1) Before calling foo g is " << g;

   int fooRetVal = foo(); // control when called
                          // do not leave up to compiler

   std::cout << "\n 2) after foo, g = " << g
             << "\n 3)    fooRetVal = " << fooRetVal
             << "\n 4)    and now g = " << g
             << std::endl;


   g = 0;  // force to 0
   std::cout << "\n 1) Before calling bar g is " << g;

   int barRetVal = bar(); // control when called
                          // do not leave up to compiler

   std::cout << "\n 2) after bar, g = " << g
             << "\n 3)    barRetVal = " << barRetVal
             << "\n 4)    and now g = " << g
             << std::endl;

   return (0);
}
int g;//未初始化!
甲级
{
公众:
~A()
{
g=10;
}
};
int foo()
{
g=3;
产科医生;
返回g;

}//
返回i你有UB,因为你没有序列点。顺便说一句,作为调用者,当我调用函数时,我总是希望结果是最终的——你返回的是
i
的值,而不是指向
i
@Jarod42的引用或指针。实际上没有UB,更像是意外的行为,但至少没有什么问题。
((expr1 << expr2) << expr3) << expr4;
              <<
            /    \
         <<     expr4
       /    \
    <<     expr3
  /    \
expr1 expr2
std::string f() {
std::string res = "abcd";
return res;
}
int g; // uninitialized!

class A
{
public:
   ~A()
      {
         g=10;
      }
};

int foo()
{
   g=3;
   A ob;
   return g;
} // <<<<<<<<<<< ob destructor called here

int bar()
{
   g=3;
   {
      A ob;
   }  // <<<<<<<<<<< ob destructor called here
   return g;
}

int t272(void)
{
   g = 0;  // force to 0
   std::cout << "\n 1) Before calling foo g is " << g;

   int fooRetVal = foo(); // control when called
                          // do not leave up to compiler

   std::cout << "\n 2) after foo, g = " << g
             << "\n 3)    fooRetVal = " << fooRetVal
             << "\n 4)    and now g = " << g
             << std::endl;


   g = 0;  // force to 0
   std::cout << "\n 1) Before calling bar g is " << g;

   int barRetVal = bar(); // control when called
                          // do not leave up to compiler

   std::cout << "\n 2) after bar, g = " << g
             << "\n 3)    barRetVal = " << barRetVal
             << "\n 4)    and now g = " << g
             << std::endl;

   return (0);
}
1) Before calling foo g is 0
2) after foo, g = 10
3)    fooRetVal = 3     <<< dtor called after return of foo
4)    and now g = 10

1) Before calling bar g is 0
2) after bar, g = 10
3)    barRetVal = 10     <<< dtor was called before return of bar
4)    and now g = 10