c+的问题+;寿命延长 我尝试理解C++临时对象生存期扩展的语义。我试着模拟简单的情况,有点惊讶

c+的问题+;寿命延长 我尝试理解C++临时对象生存期扩展的语义。我试着模拟简单的情况,有点惊讶,c++,object-lifetime,C++,Object Lifetime,下面我提供我的代码 #包括 结构C { C(const int new_a){a=new_a;}; int a=0; }; C return_num() { C数(20); std::cout想象一下这个函数: int getNumber(){ int num = 10; return num; } 此函数不作为对象返回num,它返回一个具有相同值的未命名副本(r值,如果愿意的话)。因此,它具有不同的地址 您的return\u num函数也会发生同样的情况。我怀疑获取成员地址

下面我提供我的代码

#包括
结构C
{
C(const int new_a){a=new_a;};
int a=0;
};
C return_num()
{
C数(20);
std::cout想象一下这个函数:

int getNumber(){
    int num = 10;

    return num;
}
此函数不作为对象返回
num
,它返回一个具有相同值的未命名副本(r值,如果愿意的话)。因此,它具有不同的地址


您的
return\u num
函数也会发生同样的情况。

我怀疑获取成员地址会抑制优化,因为编译器不知道如何处理所有可能的边缘情况。消除获取成员地址会使优化起作用

#include <iostream>

struct C
{
    C(const int new_a) { a = new_a; };

    int a = 0;
    struct C* t = this;
};

C return_num()
{
    C num(20);

    std::cout << "From func(): num = " << num.a << ", by adress: " << num.t << std::endl;

    return num;
}

void pass_num(const C& num)
{
    std::cout << "From func(): num = " << num.a << ", by adress: " << num.t << std::endl;
}

int main()
{
    std::cout << "\nLifetime extention:" << std::endl;
    {
        const C& ext_num = return_num();

        std::cout << "From main(): num = " << ext_num.a << ", by adress: " << ext_num.t << std::endl;
    }

    std::cout << "\nPassing by reference:" << std::endl;
    {
        C num(20);

        std::cout << "From main(): num = " << num.a << ", by adress: " << num.t << std::endl;

        pass_num(num);
    }
}
#包括
结构C
{
C(const int new_a){a=new_a;};
int a=0;
struct C*t=this;
};
C return_num()
{
C数(20);

std::coutMove构造函数通常会“窃取”参数所拥有的资源(例如指向动态分配对象的指针、文件描述符、TCP套接字、I/O流、运行线程等),而不是复制它们,并使参数保持某种有效但不确定的状态

我在您的代码中更改了以下内容,希望它能按预期工作。我将
int a
更改为
int*a

#include <iostream>

class C
{
   public:
   int *a;
   C( int new_a) 
   { 
      a = new int();
      *a = new_a;
   };
   C(const C& rhs) { std::cout << "Copy " << std::endl; this->a = rhs.a; }
   C(C&& rhs):a(std::move(rhs.a)) 
   {
      std::cout << "Move!!" <<"Address resource a " << &(*a) << ", Address of 
      resource rhs.a" << &(*rhs.a) << std::endl; rhs.a = nullptr;
      std::cout << "Value of a:: " << *a << std::endl;
   }  

  };

  C return_num()
  {
     C num(20);

     std::cout << "From return_num(): num = " << *num.a << ", Address of resource a : 
     "<< &(*num.a)<< std::endl;
    return (std::move(num));
  }

  void pass_num(const C& num)
  {
     std::cout << "From pass_num(): num = " << *num.a << ", by adress: " << &num.a << 
     std::endl;
  }

  int main()
  {
      std::cout << "\nLifetime extention:" << std::endl;
      {
         const C& ext_num = return_num();

         std::cout << "From main() 1 : num = " << *(ext_num.a) << ", by resource 
         adress: " << &(*ext_num.a) << std::endl;
      }

      std::cout << "\nPassing by reference:" << std::endl;
      {
         C num(20);

         std::cout << "From main() 2 : num = " << *num.a << ", by adress: " << &num.a 
         << std::endl;

         pass_num(num);
       }
       return 0;
    }

我希望这会有帮助!

C return_num()
正在返回一份
C
对象的副本挑剔:为什么要将
const int新建为一个
参数const?
ext_num.t
可能与
&ext_num
不匹配。我想你也有一份副本。@TEDLYNGOM我想你是对的!你什么时候会使用
return_num()
方法,您将获得
C
结构的副本,
ext\u num
将具有指针(
C::t
)我不知道为什么这个答案是正确的accepted@Raffallo你能澄清一下你的答案吗?第一个问题是:为什么你认为复制的结构的指针,如果它真的被复制了,指向的是不存在的结构。从我的观点来看,它指向“this”,因为它包含“this”第二个问题:你能澄清为什么两个同时存在的对象有相同的地址吗?@alex
t
只是一个
C*
,如果
C
被复制,它可能会指向某个曾经有一个活的
C
的地方。如果省略复制,它将指向活的对象。@alex很简单。
struct C*t=this;
表示构造函数创建指向当前结构的指针。何时使用
return_num();
方法,结构仍然被复制,因此新结构是上一个结构的副本,导致指向该结构的指针也从上一个复制而来。因此
C::t
指针是相同的,但是如果您选中
&num
&ext_num
,您将看到差异。要解决这个问题你应该把这个:
C return\u num()
改为:
C&return\u num()
谢谢,但我认为编译器会理解下面的行const C&ext\u num=return\u num();就好像我们想要获取引用的一个副本,并通过这个引用保存变量的值,直到引用的副本消失。这是正确的吗?
Lifetime extention:
From return_num(): num = 20, Address of resource a : 0x7fffeca99280
Move!!Address resource a 0x7fffeca99280, Address of resource rhs.a0x7fffeca99280
Value of a:: 20
From main() 1 : num = 20, by resource adress: 0x7fffeca99280

Passing by reference:
From main() 2 : num = 20, by adress: 0x7ffff466f388
From pass_num(): num = 20, by adress: 0x7ffff466f388