Как написать конструктор копирования для шаблона класса, который хранит указатели в std :: map? - PullRequest
1 голос
/ 22 июня 2011

Я только начал с c ++, и у меня есть некоторые проблемы с созданием шаблона класса с именем auto_map , который использует std :: map , который должен хранить не объекты, а их указатели.

Что-то вроде:

std::map<K*, V*, cmp> m;

Что я использую так:

auto_map<std::string, std::string> t;
t.insert( new std::string( "A" ), new std::string( "B" ) );

cpm:

struct cmp
{
  bool operator()(K *a, K *b) { return *a < *b; }
  bool operator== (K *a) { return (*a); }
};

Функция вставки ищет любые дубликаты перед вставкой:

void insert(K* k, V* v)
{
  for (typename std::map<K*, V*, cmp>::iterator i=m.begin(); i!=m.end(); ++i)
  {
    if ( (*k) == (*(*i).first) ) 
    {
      delete (*i).first;
      delete (*i).second;
      m.erase(i);
    }          
  }
  m.insert(std::make_pair(k,v));
}

И конструкторы:

auto_map(){}
~auto_map()
{
  for (typename std::map<K*, V*, cmp>::iterator i=m.begin(); i!=m.end(); ++i)
  { 
    delete (*i).first;
    delete (*i).second;
    m.erase(i);
  }
}

Они работают нормально, но теперь вы, наверное, поняли идею. Поэтому возникает вопрос, в котором я не уверен:

Как мне написать для него конструктор копирования?

auto_map (auto_map& original)
{
  for (typename std::map<K*, V*, cmp>::iterator i=original.m.begin(); i!=original.m.end(); ++i)
  {

    // what goes in here that will call each objects copy-constructor?
    // how not to get complained about invalid conversions?... 

    // K newk = (*(*i).first);
    // V newv = (*(*i).second);
    // m.insert(std::make_pair(newk, newv));
    // gives compiler error: cannot convert ‘const CntInteger’ to ‘CntInteger* const’ in initialization
    // cannot convert ‘const CntInteger’ to ‘CntInteger*’ in initialization


  }
};

Большое спасибо за ответы и исправления!

Ответы [ 2 ]

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

Чтобы ответить на ваш буквальный вопрос из заголовка: вы не можете написать новый конструктор копирования для существующего шаблона класса std::map.

Далее, вы уверены, что действительно хотите реализовать все (двоичное дерево)) структура карты с O (log n) поиска снова для вашего контейнера с добавленными соображениями управления памятью std::shared_ptr (подумайте об объектах с пользовательскими удалителями)?Почему бы просто не поместить shared_ptr s в вашу карту?

std::map<std::shared_ptr<Key>, std::shared_ptr<Value>>

Обновление: Не могли бы вы использовать Контейнеры указателей Boost ?Или вам нужно, чтобы ваши ценности тоже были указателями? Как насчет a boost::ptr_unordered_map<std::string, T> со значениями T*?

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

Хотя я сомневаюсь в полезности того, что вы пытаетесь сделать, вот вам:

auto_map (auto_map& original)
{
    K * kp = 0;
    V * vp = 0;
    try
    {
        for (typename std::map<K*, V*, cmp>::iterator i=original.m.begin();
             i!=original.m.end();
             ++i, kp=0, vp=0)
        {
            kp = new K(*(i->first));
            vp = new V(*(i->second));
            m[kp] = vp;                  
        }
    }
    catch(...)
    {
        delete kp;
        delete vp;

        // write a destroy function that does the same thing
        // as your destructor does now
        destroy();
        throw;       
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...