jjzjj

c++ - C++生命周期延长的问题

coder 2024-02-23 原文

我试图理解 C++ 临时对象生命周期延长的语义。我试图模拟简单的情况,但有点惊讶。

下面我提供我的代码。

#include <iostream>

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

    int a = 0;
};

C return_num()
{
    C num(20);

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

    return num;
}

void pass_num(const C& num)
{
    std::cout << "From func(): 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(): num = " << ext_num.a << ", by adress: " << &ext_num.a << std::endl;
    }

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

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

        pass_num(num);
    }
}

这里是主要问题:return_num()从我的角度来看,工作很奇怪,因为我期望变量的地址,我试图在 main 中输出它, 将与 return_num() 中的内部相同.你能解释一下为什么不是吗?

例如 pass_num()输出地址匹配我在 main 中得到的外部地址.

这是示例输出:

生命周期延长:
从 func(): num = 20, by address: 0x7fff44fc8b4c
从 main(): num = 20, by address: 0x7fff44fc8b70

通过引用:
从 main(): num = 20, by address: 0x7fff44fc8b6c
从 func(): num = 20, by address: 0x7fff44fc8b6c

最佳答案

移动构造函数通常“窃取”参数持有的资源(例如指向动态分配对象、文件描述符、TCP 套接字、I/O 流、运行线程等的指针)而不是复制它们,然后离开一些有效但不确定状态的参数。

Please see Move Constructor

我更改了您代码中的以下内容,希望它能按预期工作。我将 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;
    }

以上代码产生以下输出:

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

希望对您有所帮助!

关于c++ - C++生命周期延长的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56750030/

有关c++ - C++生命周期延长的问题的更多相关文章

  1. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  2. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  5. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  6. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  9. 【高数】用拉格朗日中值定理解决极限问题 - 2

    首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有,  也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加

  10. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

随机推荐