Будет ли это считаться хорошим кодом C ++ - PullRequest
1 голос
/ 09 ноября 2010

У меня есть вектор с необработанными указателями (нет, я не могу использовать умные указатели), и я хочу добавить элементы в список в цикле 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, если кто-то там есть, то я хотел бы услышать об этом.

Ответы [ 5 ]

5 голосов
/ 09 ноября 2010

Ну, это утечка памяти, так что это плохо.Можете ли вы использовать Pointer Container ?

Причина утечки этого кода заключается в том, что вы создаете объекты в куче, используя new, но никогда не вызываете delete для них.

Что касается вашего комментария, если у вас есть объект, который вручную управляет каким-либо ресурсом, вам необходимо Большая тройка .

0 голосов
/ 09 ноября 2010

Если вы не можете использовать умные указатели, тогда используйте boost :: ptr_vector .

Обратите внимание, что если вы используете TinyXml, управление памятью в XmlNode, вероятно, продиктовано библиотекой - недавняя история iirc заключается в том, что многие из ваших проблем связаны с правильным пониманием владения памятью и парадигмы выпуска дляэта библиотека.

Какое управление памятью мне нужно очистить при использовании TinyXml для C ++?

Какой самый лучший анализатор открытых XML для C ++?

0 голосов
/ 09 ноября 2010

Я буду считать, что в конце метода у вас есть цикл для вызова delete для каждого члена vector.

Есть еще проблемы, в частности, проблемы безопасности исключений.

  • Если между созданием Request и его регистрацией в vector что-то не получилось, вы потеряли память. Одним из решений является временное использование scoped_ptr для удержания в памяти, push_back с ptr.get(), а затем вызов метода release, поскольку теперь память принадлежит vector.
  • Если что-то выбрасывается между точкой, когда вы создали предметы в vector, и точкой, где вы их уничтожили, вам нужно поймать исключение, уничтожить предметы и затем отбросить.

Могут быть и другие, но RAII был изобретен по причине, без которой действительно трудно обойтись (правильно ...)

0 голосов
/ 09 ноября 2010

Если вы не можете (или не можете) использовать умные указатели, возможно, вы могли бы использовать простой диспетчер памяти, подобный этому:

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.
0 голосов
/ 09 ноября 2010

Быстрое улучшение может состоять в том, чтобы извлечь класс RequestVector из std::vector<Request*>, добавить метод ClearRequests (который удаляет все объекты Request и очистить вектор) и выполнить вызов деструктора ClearRequests.(На самом деле агрегирование вектора в RequestVector может быть лучшим выбором, но производный класс выполняется быстрее).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...