Определение карты со структурой внутри - PullRequest
0 голосов
/ 09 июня 2011

У меня есть структура, как

struct category {
    int id,newID;
    std::string name;
};

и карта типа

std::map<std::string, category> categories;

безопасно ли вставлять детали на карту как

category x = {1,2,"Name"};
category y = {2,3,"Mike"};
categories["FIRST"]=x;
categories["SECOND"]=y;

или я должен объявить карту как

std::map<std::string, category*> categories;

а сделать указатели структуры и вставить его? что безопаснее?

Ответы [ 6 ]

2 голосов
/ 09 июня 2011

Что вы подразумеваете под безопаснее? Оба метода просто отлично. При использовании второго способа вы должны обязательно удалить объекты вашей категории. На первом они удаляются автоматически при удалении вашей карты.

Первый медленнее, если вам нужно много разносить объекты, так как вы будете делать копии. Второй просто скопировал бы указатели.

Так что вам решать, какой из них соответствует вашим потребностям.

1 голос
/ 09 июня 2011

На ваш вопрос невозможно ответить без контекста.

Наивным ответом может быть «вставка самих структур безопаснее, потому что вам не нужно беспокоиться об утечках памяти».Однако такой ответ на самом деле не является удовлетворительным.

Чтобы получить лучший ответ, необходимо учитывать несколько факторов:

  1. Предполагается, что ваш struct должен быть копируемым?Другими словами, имеет ли смысл в вашей прикладной области иметь несколько копий одной структуры?Если нет, вам следует использовать указатели.
  2. Ваш struct в его текущей форме является копируемым и имеет глубокую семантику копирования.Существует ли реальная вероятность того, что в будущем вы добавите в нее элементы, что приведет к нарушению семантики глубокого копирования?Если это так, вы будете вынуждены иметь дело с этим так или иначе.Это связано с предыдущим пунктом, поскольку копируемость и семантика копирования вашего struct должны влиять на ваше решение.
  3. Вероятно, в вашем map будет много записей?Вероятно, будет много записей, где ключи различаются, а значения нет?В этом случае использование указателей приведет к экономии памяти.
1 голос
/ 09 июня 2011

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

Если вы используете указатели, вы, вероятно, захотите создать экземпляры в куче, что означает ручное управление памятью, которое подвержено ошибкам.

Единственное преимущество второго решения (с точки зрения безопасности) заключается в том, что объекты должны быть копируемыми. Если объект вручную управляет какими-либо ресурсами, вы должны убедиться, что ваш конструктор копирования и оператор присваивания реализованы правильно.

0 голосов
/ 09 июня 2011

Вот мои заметки о том, как сделать этот код более безопасным:

  1. Я бы создал конструктор для struct category:

    struct category {
        category( int id, int newID, const std::string& name) : 
            id(id), newID(newID), name(name) {}
        int id,newID;
        std::string name;
    };
    

    Это даст вамнапример, шанс не нарушить ваш код, изменив структуру id и newID.Теперь вы можете инициализировать его как categories["FIRST"]=category(1, 2, "Name");

  2. Я бы использовал умные указатели вместо простых указателей:

    std::map<std::string, boost::shared_ptr<category> > categories;
    
  3. std::map<std::string, category> isХорошо, но он скопирует объекты category.Если они достаточно большие, это может быть проблемой производительности.

0 голосов
/ 09 июня 2011

Я бы обернул объекты категории в умный указатель и сохранил бы умный указатель.Он менее тяжелый, чем хранение всего объекта, обеспечивает доступ к реальному объекту и автоматически очищается.

0 голосов
/ 09 июня 2011

Отлично [ваш первый пример]. Вот как ты должен это сделать.

Вы должны вводить косвенное и динамическое распределение [ваш второй пример] только тогда, когда вам действительно необходимо, так как тогда вам нужно управлять временем жизни объекта, и оно более подвержено ошибкам.

...