簡體   English   中英

指向堆棧分配對象的指針和引用

[英]Pointers and references to stack-allocated object

假設我有以下代碼(可能被簡化了,但我認為足夠了):

struct BigObject {
   A a;
   B b;
};

struct A { ... };

struct B {
    A const* a_ptr;
    MyOtherClass someMethodUsingA() { ... }
}

class BigObjectBuilder {
    BigObject build() {
        BigObject o;
        o.a = buildA();
        o.b.a_ptr = &(o.a);

        return o;
    }
}

問題在於&(oa)稍后可能指向任何內容,因為返回o的地址可能已更改(調用move或copy構造函數)。 現在我發現&(oa)在大多數情況下都是相同的,因此調用*(oba_ptr)不會導致段錯誤。 (我認為這是由於RVO所致,因為那時o未被移動)。 無論如何,只要我不確定o的地址沒有更改,此代碼就是不正確的。

一個明顯的解決方案是要求動態分配我的BigObject:

auto o_ptr = make_unique<BigObject>();

這個解決方案還不錯(沒有泄漏,並且解決了先前的問題。),但是我仍然覺得它很不完善:我不需要動態分配,我只需要為BigObject提供一個固定地址即可。 我認為這將是Java的處理方式。 另一種解決方案是在B中使用副本,但是oa中的所有更改都不會影響oba,而我也不想這樣做。

第三種解決方案是在B中沒有A的副本,ptr或引用,並在方法B :: someMethodUsingA()的參數中傳遞A。 但是,再次找到調用此函數時要傳遞的參數可能很繁瑣。 有時,讓B類擁有指向A類的指針感覺更自然。

現在,我在代碼中一次又一次地發現了這個問題:我想構建一個復雜的對象,並且子對象之間相互引用。 根本的問題是該對象不是“就地”創建的,它可能會在以后的構建過程中移動(但並非在構建完所有東西之后)。

他們是否有適用於此的已知模式? 我想這是一個非常普遍的問題,如果不是,那一定是因為我沒有以正確的方式構建系統...

有沒有辦法確保某種RVO? 我的意思是,由標准而非編譯器保證。 像編譯器警告說“ BigObject”不能移到其他地址之類的東西”

我還考慮過刪除移動復制ctor和賦值運算符。 但是,即使在實踐中什么都沒有移動,我也無法按值返回對象。

歡迎為您工作的任何份額!

我不明白為什么在struct BigObject需要一個struct對象及其指針。 您可以這樣設計結構:

struct A { ... };
struct BigObject {
   A a;
   MyOtherClass someMethodUsingA() { /* Here you can use the variable a. */ }
};

如果仍然想用自己的方式進行編碼,則可以為struct BigObject添加copy-construct和assign-construct函數,如下所示:

struct BigObject 
{
     A a;
     B b;

     // copy-construct function
     BigObject(const BigObject& old) 
     {
         a = old.a;
         b = old.b;
         b.a_ptr = &a; // pay attetion
     }  

     // assign construct function
     BigObject& operator=(const BigObject& old)
     {
          if (this == &old) // avoid self-assignment
          {
              return *this;
          }

          a = old.a;
          b = old.b;
          b.a_ptr = &a; 

          return *this;
     }
};

在B的函數中添加A引用參數,然后BigObject調用函數時,它可以傳遞其A。A和B應該是私有的。 如有必要,將包裝函數添加到BigObject,該函數將重定向到對A和B的調用,並根據需要傳遞A參數。

不要編寫要求RVO起作用的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM