簡體   English   中英

如何取消引用用New創建的指針而不進行復制?

[英]How can I dereference a pointer created with New without copying?

在下面的代碼片段中,我通過new運算符創建了一個對象,並將其分配給指針。 我想做的是添加它指向矢量的對象。 似乎正在發生的事情是我正在很好地創建對象,然后取消引用它時,這將創建對原始對象的引用。 因此,當我將此對Object的引用分配給矢量時,它會創建一個副本,而我想要實際的對象。 任何幫助將非常感激。

std::vector<Object> OBJVec;

Object *O = new Object();
/*Edits some of the internals*/
addToVec(*O); //Here is the beginning of the problem: this passes a reference to the content of O.

void addToVec(Object OParam){ //Here Creates a copy of O instead of passing the actual content.
    OBJVec.push_back(OParam); // Pushes a copy of content instead of content.
}

*注意:上述代碼是我要完成的代碼的非常簡化的版本。

關於此代碼與之交互的代碼的注釋,該代碼與OpenGL交互,因此OBJVec必須包含對象。

我已經在這個問題上工作了一段時間,任何幫助都會很棒。

行為正確

這是std::vector::push_back的簽名

void push_back( const T& value );
void push_back( T&& value );

現在,當您取消對指針的引用時,便有了對原始對象的引用。 將左值引用傳遞給push_back將選擇第一個重載。

在第二種情況下,它也是一個左值,因此仍然會選擇第一個重載...您不能在push_back上閃避復制,除非您傳遞了一個rvalue或顯式的std::move

如果要使用指針,則讓您的容器成為指針的容器。 如果要引用,則讓您的容器成為對象的reference_wrapper

但是,如果您執行這些路由,則還有額外的內存管理工作要做

由於std::vector處理其自己的內存分配(默認情況下) 1 ,因此您無法在其外部分配元素,然后使vector指向該元素,除非您單獨使vector的value_type成為指針,即std::vector<Object*> ,並將指針本身傳遞給addToVec

std::vector<Object*> OBJVec; // Make a vector of pointers instead of objects
Object *O = new Object();

addToVec(O); // Do not dereference here

void addToVec(Object *OParam) { // Use a pointer here as the argument
    OBJVec.push_back(OParam);
}

但是,一旦將元素從向量中刪除並且不再使用它們,則需要重新分配元素。 為了簡化此操作,您可以改用unique_ptr的向量,它們是智能指針 ,可以一次不再需要時為您取消分配對象。

如果需要指針向量,則不能應用此替代方法。 然后,您不能對vector之外的每個單個對象使用new 這必然導致對象被分開分配,而不是確保任何采用數組的OpenGL函數所要求的連續內存布局。 您可能需要分配一個帶有new Object[count]的數組,或者干脆完全放棄手動存儲的想法,只使用對象向量而不在其外部分配元素。


1)您可以更改該行為,但是像現在這樣,仍然不可能在向量之外自行分配每個元素。

我認為這應該更好(這樣您就不會復制任何內容):

std::vector<Object*> OBJVec;
Object *O = new Object();

addToVec(O); 

void addToVec(Object* OParam){
    OBJVec.push_back(OParam);
}

在C ++ 98中,沒有移動的概念,因此您將不得不使用指針向量代替,然后在其中復制對原始對象的引用。 在C ++ 11中,您確實具有移動語義,因此您可以使用std::move從字面上移動對象。 但是,我不確定這是否是個好主意。

首先,這些天不使用裸露的new 您應該使用一些智能指針或您自己的RAII包裝器。 在您的情況下,我只使用std::unique_pointer (C ++ 11-或boost::unique_pointer ),然后簡單地使用std::vector<std::unique_pointer<your_type>>即可安全地移動指針(您可以無法復制std::unique_pointer )。 這種方法沒有真正的開銷,因此,如果需要堆分配和唯一所有權,這可能是解決方法。

如果您不需要堆分配並且您使用的是c ++ 11,那么您實際上不需要首先使用指針。 只需創建您的對象並將其移動到矢量中即可,但是請確保不要再使用原始對象!

暫無
暫無

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

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