[英]Creating an object on the stack then passing by reference to another method in C++
我來自C#背景到C ++。 假設我有一個方法在堆棧的方法中創建一個對象,然后我將它傳遞給另一個類方法,該方法將它添加到一個memeber向量。
void DoStuff()
{
SimpleObj so = SimpleObj("Data", 4);
memobj.Add(so);
}
//In memobj
void Add(SimpleObj& so)
{
memVec.push_back(so); //boost::ptr_vector object
}
這是我的問題:
我意識到這些對C ++程序員來說可能是顯而易見的。
標記
實現您要做的事情的最簡單方法是將對象的副本存儲在普通的STL容器中(例如std::vector
)。 answer ). 如果這些對象重量級且復制成本 ,您可能希望在堆上分配它們將它們存儲在容納足夠智能指針的容器中,例如boost::shared_ptr
(請參閱@ 答案中的示例)。
另一種可能性是將boost::ptr_vector
與boost::ptr_vector_owner
結合使用; 最后一個類負責“擁有”存儲在關聯的ptr_vector
的對象,並在超出范圍時刪除所有指針。 有關ptr_vector
和ptr_vector_owner
更多信息,您可能需要查看本文 。
要實現您的目標,您應該使用shared_ptr :
void DoStuff()
{
boost::shared_ptr<SimpleObj> so(new SimpleObj("Data", 4));
memobj.Add(so);
}
//In memobj
void Add(boost::shared_ptr<SimpleObj> so)
{
memVec.push_back(so); // std::vector<boost::shared_ptr<SimpleObj> > memVec;
}
是的,一旦你的函數離開范圍,你的對象將從堆棧中彈出。 您應該使用new
創建一個堆對象,並在向量中添加指向該對象的指針。
如前所述,一旦第一個函數超出范圍,向量中的指針將指向未定義的內容
該代碼將無法編譯,因為在Add函數中,您試圖將整個對象推送到需要指向對象的指針的向量中。
如果您要獲取該對象的地址並將其推送到向量上,那么這將是危險的,因為原始對象很快將從堆棧彈出,並且您存儲的指針將指向未初始化的內存。
如果你使用普通向量而不是指針向量,則push_back調用將復制整個對象而不是指針,因此它是安全的。 但是,這並不一定有效,對於來自C#,Java或Python世界的人來說,“復制一切”方法可能並不直觀。
為了存儲指向對象的指針,必須使用new創建它。 否則它會在超出范圍時消失。
這里介紹的問題最簡單的解決方案是使用std :: vector而不是boost :: ptr_vector,因為這樣push_back會復制向量中的對象
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.