c++中引用和智能指针的简单问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ruokw
V2EX    问与答

c++中引用和智能指针的简单问题

  •  
  •   ruokw 2021-02-04 17:20:51 +08:00 via Android 1877 次点击
    这是一个创建于 1740 天前的主题,其中的信息可能已经有所发展或是发生改变。
    传入对象引用,例如 json-value ( A )。现在想把它包装成新对象( B{A})返回,但是底层指向同一个对象。而且 B 要支持无参构造。使用智能指针去包装 A 会出现超过域后过早释放空间的问题。想问下这种情况下有什么好的解决方法吗?
    第 1 条附言    2021-02-04 18:31:30 +08:00
    B f(A& a)
    {
    B b;
    b.a=shared_ptr<A>(&a);
    return b;
    }

    void m(A& a)
    {
    {
    B b=f(a);
    (*b.a)=xxx;
    }
    print a; // error
    return ;
    }
    第 2 条附言    2021-02-04 21:04:14 +08:00
    谢谢大家了,后来想想也是,不让智能指针管理生命周期,就直接用 raw 指针就行了。蠢了,逃~ 哈哈
    23 条回复    2021-02-04 22:23:03 +08:00
    yianing
        1
    yianing  
       2021-02-04 17:39:39 +08:00 via Android
    那在有参构造的时候传入智能指针的拷贝不就行了吗?
    ruokw
        2
    ruokw  
    OP
       2021-02-04 17:50:37 +08:00 via Android
    @yianing 现在问题是 A 应该是在 B 之后才会被释放,但是 B 保存 A 的智能指针,在 B 死亡时会提前释放掉 A 。
    yianing
        3
    yianing  
       2021-02-04 18:12:58 +08:00 via Android
    @ruokw B 死亡时只会将 A 的引用数减一,并不会释放掉指针指向的内存吧,只有引用数变为 0 的时候才会真正释放内存
    wutiantong
        4
    wutiantong  
       2021-02-04 18:19:10 +08:00
    你没有描述清楚你的问题
    ruokw
        5
    ruokw  
    OP
       2021-02-04 18:31:55 +08:00 via Android
    @wutiantong 补充了
    ruokw
        6
    ruokw  
    OP
       2021-02-04 18:32:02 +08:00 via Android
    @yianing 补充了
    wevsty
        7
    wevsty  
       2021-02-04 18:51:30 +08:00
    首先把传入的引用转换为智能指针是一种强烈不推荐的做法。
    其次,shared_ptr 在超过生存周期的时候会自动对引用计数减 1,如果引用计数为 0 就会去 delete 管理的对象。如果不想 shared_ptr 指针去 delete 这个对象,要不然增加引用计数,要不然就延长 shared_ptr 的生存周期。
    yianing
        8
    yianing  
       2021-02-04 19:03:34 +08:00 via Android
    好家伙,都用智能指针了为什么还要去获取裸指针呢?
    ruokw
        9
    ruokw  
    OP
       2021-02-04 19:04:16 +08:00 via Android
    @wevsty 这个能明白。现在的问题是实际上 B 被作为类型的集合,用来统一一类函数的返回类型,B{int string long A},如果 B 里面 A 用引用,就又意味着 B 不能无参构造了。 所以现在有啥好的方法? 还是说只能整个重新设计?
    ruokw
        10
    ruokw  
    OP
       2021-02-04 19:09:11 +08:00 via Android
    @yianing 你是说 shared_ptr(&a)么? 至少我现在在 mxvc2011 里面对引用 a 构造智能指针要用&a 。这点也比较难理解,为啥引用还有指针?
    yianing
        11
    yianing  
       2021-02-04 19:12:50 +08:00 via Android
    @ruokw 智能指针创建的正确使用姿势是 std::make_shared,你这把传进来的实例引用取地址绝对有问题啊
    imjamespond
        12
    imjamespond  
       2021-02-04 19:36:09 +08:00 via Android
    可以用 weak ptr 啊。。。
    ruokw
        13
    ruokw  
    OP
       2021-02-04 19:38:42 +08:00 via Android
    @yianing 这个也能明白,但是现在情况是 B 不仅包装包装 a 而是包装 a 的子对象比方说 a 是 json::Value ,b=shared_ptr(a["num"])。 这时候可能光 a 是智能指针都不够
    ruokw
        14
    ruokw  
    OP
       2021-02-04 19:39:56 +08:00 via Android
    @imjamespond 用 weak 还是得先有 shared 哈,有 shared 就又回到最初的说的了
    hazardous
        15
    hazardous  
       2021-02-04 19:53:17 +08:00
    使用 shared_ptr 第二个参数:自定义 deletor
    hazardous
        16
    hazardous  
       2021-02-04 20:02:23 +08:00
    还有个问题是很难保证传入 A 的引用一定是 new 出来的对象,如果是个栈上对象那 shared_ptr 释放的时候就崩了。
    ruokw
        17
    ruokw  
    OP
       2021-02-04 20:08:01 +08:00 via Android
    @hazardous 我把 deletor 设置成空,最原始的 a 在栈上,现在只是说用智能指针代替引用。在我现在这个场景应该够用了。谢谢你了哈
    wutiantong
        18
    wutiantong  
       2021-02-04 20:40:01 +08:00
    楼主这 c++纯属瞎写啊。。。

    首先我们有 enable_shared_from_this ( https://en.cppreference.com/w/cpp/memory/enable_shared_from_this ),
    其次我们有 aliasing constructor for shared_ptr ( https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr #8 )
    mainjzb
        19
    mainjzb  
       2021-02-04 20:55:30 +08:00
    ..你已经把生死权交给 b 了。
    所以 b 死了,拉着 a 一起死很正常。
    不想交给 b 就用普通指针。所以用智能指针的意义何在。
    ruokw
        20
    ruokw  
    OP
       2021-02-04 20:55:44 +08:00 via Android
    @wutiantong 哈哈 新手上路嘛,我看看你说的哈
    mainjzb
        21
    mainjzb  
       2021-02-04 20:56:34 +08:00
    要么 a 从一开始就用 share 指针。
    要么自己管理,都不用智能指针
    ruokw
        22
    ruokw  
    OP
       2021-02-04 21:02:06 +08:00 via Android
    @mainjzb 后来想想也是。。。蠢了(*`*) 哈哈
    nicebird
        23
    nicebird  
       2021-02-04 22:23:03 +08:00
    初学者吧,低级错误。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1288 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 17:07 PVG 01:07 LAX 09:07 JFK 12:07
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86