簡體   English   中英

用於放置在一組函數中傳遞的參數的結構

[英]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_deletershared_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中定義一個析構函數,該析構函數將刪除其所有指針。 另一種方法是在您注冊以后應刪除的對象的地方。 或者,您也可以按照其他答案中的建議使用現有的參考計數工具。

不,您對myAsomec范圍的想法是錯誤的。 您現在所擁有的沒有什么錯-盡管我個人認為引用將是對指針的一種更好的選擇。

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.

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