簡體   English   中英

這會被認為是好的C ++代碼嗎?

[英]Would this be considered good C++ code

我有一個帶有原始指針的向量(不,我不能使用智能指針),我想在for循環中將項添加到列表中。 我做了一個小試用項目,我想知道這在指針管理方面是否被認為是好的C ++代碼。

請僅考慮原始指針管理,我對我正在嘗試解決的這個特定問題的智能指針不感興趣。

一個簡單的對象:

class Request
{
public:
    std::string name;

};

std::vector<Request*> requests;

for (int i = 0; i < 5; i++)
{
    std::stringstream ss;
    ss << "elemenent ";
    ss << i;

    std::string s = ss.str();

    Request* req = new Request();   
    req->name = s;

    requests.push_back(req);

}

編輯:

所以我想解決的問題是將DOMNode *添加到此庫中的向量中。
我開始覺得嘗試為我的項目編寫一個包含我需要的部件的包裝器是一個壞主意。 或者圖書館也不好? 我沒有使用smart_ptr正常工作,如果有人在那里,那么我想聽聽它。

好吧,這會泄漏內存,所以很糟糕。 你能用指針容器嗎?

此代碼泄漏的原因是您使用new在堆上創建對象,但您從不對它們調用delete

至於你評論,如果你有一個手動管理一些資源的對象,你需要三巨頭

如果您無法(或允許)使用智能指針,可能您可以使用這樣的簡單內存管理器:

template <class T>
class MemManager
{
public:
  typedef std::vector<T*> Vec;
  ~MemManager ()
  {
    size_t sz = v_.size ();
    for (size_t i = 0; i < sz; ++i)
      delete v_[i];
  }
  T* pushNewObject () 
  {
    T* t = NULL;
    try
    {
        t = new T;
        if (t != NULL)
           v_.push_back(t);            
    }
    catch (std::bad_alloc& ex) { /* handle ex */ }
    return t;
  }
  const Vec& objects() const { return v_; }
private:
  Vec v_;
};

// test
{
  MemManager<Request> mm;
  for (int i = 0; i < 5; i++)
    {
      std::stringstream ss;
      ss << "elemenent ";
      ss << i;

      std::string s = ss.str();

      Request* req = mm.pushNewObject();
      req->name = s;    
    }
} // all Request objects will be deleted here when 
  // the MemManager object goes out of scope.

我會認為你在方法的最后有一個循環來調用vector每個成員上的delete。

仍然存在問題,特別是異常安全問題。

  • 如果在創建Request和在vector注冊之間拋出任何內容,則會丟失內存。 一種解決方案是臨時使用scoped_ptr來保存內存, push_back使用ptr.get()然后調用release方法,因為現在內存由vector擁有。
  • 如果在vector創建項目的點與銷毀它們的點之間拋出任何內容,則需要捕獲異常,銷毀項目,然后重新拋出。

可能還有其他人,但是出於某種原因發明了RAII,沒有(正確...)真的很難做到

如果你不能使用智能指針,那么使用boost :: ptr_vector

請注意,如果您使用的是TinyXml ,則XmlNode內存管理可能由庫決定 - 最近的歷史記錄iirc是您的許多問題與正確理解此庫的內存所有權和發布范例有關。

在使用TinyXml for C ++時,我需要清理哪些內存管理?

什么是C ++最好的開放XML解析器?

一個快速改進可能是從std::vector<Request*>派生一個RequestVector類,添加一個ClearRequests方法(刪除所有Request對象並清除向量)並使它的析構函數調用ClearRequests (實際上,在RequestVector聚合向量可能是更好的選擇,但派生類更快完成)。

暫無
暫無

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

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