[英]A struct for putting in parameters passed around in a set of functions
我需要能夠靈活地更改傳遞給不同函數的參數的靈活性,具體取決於調用函數的位置,因此我決定將所有參數都放在一個結構中,但是這些參數大多數都是結構或類本身並且我想選擇保留它們為NULL,因此我必須將指針傳遞給結構/類。
struct A
{
otherB* b; // NULL should be a valid value
otherC* c;
};
但是現在我的問題是,在這些指針周圍傳遞A將是唯一復制的東西,因此,如果執行以下操作,將會出現問題嗎?
void func(A& a) //non const cause I wanna change contents of A.
{
a.b = new b();
}
A myA;
otherC somec; // all these are currently automatic variables in my pgm.
myA.c = &somec;
func(myA); //myA goes out of scope? so I've lost all pointers assigned and since somec is out of scope too, I have a problem?
解決此類問題的最佳方法是什么?我想要能夠將NULL傳遞給我的任何參數的靈活性,但是不確定在各處使用原始指針是否是個好主意?
要解決資源管理問題,應使用boost::shared_ptr
(或C ++ 0x中的std::shared_ptr
)。
struct A
{
boost::shared_ptr< otherB > b;
boost::shared_ptr< otherC > c;
};
void func(A& a)
{
a.b = boost::make_shared< otherB >();
}
A myA;
otherC somec;
myA.c = boost::shared_ptr< otherC >(&somec, null_deleter());
func(myA);
當myA
超出范圍時,所有資源都會自動釋放。 由於somec
是在堆棧上分配的,因此我們將其包裝在使用null_deleter
的shared_ptr
,如下所示:
struct null_deleter {
void operator()(void *) { }
};
這不會刪除對象,它不會做任何事情(這正是我們想要的堆棧分配對象)。 但是請記住,您必須確保somec
壽命比myA
,否則您將遇到訪問沖突。
boost::optional<>
允許您測試是否設置了該字段。
簡單的例子(不會編譯,我甚至沒有對其進行遠程測試,從理論上講,這是應該起作用的方式)
struct params
{
boost::optional<int> a;
boost::optional<foo> b;
boost::optional<bar> c;
};
void func(params& p)
{
if (p.a)
{
// do stuff with a
}
if (p.b)
{
// do stuff with b
}
if (p.c)
{
// do stuff with c
}
else
p.c = bar(); // again copy constructed and now initialized...
}
params p;
p.a = 1;
p.b = foo(); // copy constructed, however you can store a reference in the optional too.
// c is uninitialized
func(p);
// when p goes out of scope, everything is gone..
基本上,您必須分析所有權 ,即誰可以分配對象,誰不再使用對象,誰負責刪除對象。
需要記住的一件事是,如果將動態分配的事物與放置在棧中的事物混合在一起,則根本無法對它們應用delete
,因為無法刪除棧中的事物。
一種方法是僅使用new
並在A
中定義一個析構函數,該析構函數將刪除其所有指針。 另一種方法是在您注冊以后應刪除的對象的地方。 或者,您也可以按照其他答案中的建議使用現有的參考計數工具。
不,您對myA
和somec
范圍的想法是錯誤的。 您現在所擁有的沒有什么錯-盡管我個人認為引用將是對指針的一種更好的選擇。
void func(A& a) //non const cause I wanna change contents of A.
{
a.b = new b();
}
int main() {
A myA;
otherC somec; // all these are currently automatic variables in my pgm.
myA.c = &somec;
func(myA);
// myA and somec are still perfectly in scope to be saved, or deleted, or w/e as you like
}
從描述中還不清楚,但是如果由於somec超出范圍而遇到問題,那只能是因為func正在保存指針的副本。 不要那樣做:在函數中,復制對象,而不是指針。
PS:如果大多數時間大多數指針都是空的,則應考慮使用以下語法糖:
struct A
{
// pointer members...
A() : // ... set all pointers to null...
A& withB( B const& someB ) { otherB = &someB; return *this ; }
A& withC( C const& someC ) { otherC = &someC; return *this ; }
// And so on for all of the rest of the pointers.
};
func( A().withC( somec ) );
不知道它是否適合您的情況,但這通常很方便。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.