2012-01-26 2 views
1

Я работаю над библиотекой, где пользователи должны иметь возможность использовать статические глобальные экземпляры. Эти случаи (время запуска, прежде чем основной) регистрируются в другой глобальный вектор, который затем может быть использован ...Саморегистрационный глобальный объект

В настоящее время он проходит примерно так ...

class A; 

std::vector<A*> v; 

class A { 
public: 
    A (int i) : i(i) { 
     v.push_back(this); 
    } 

    int get() const { 
     return this->i; 
    } 
private: 
    int i; 
}; 

A a(1); 
A b(2); 

int main() 
{ 
    for (A* const& c : v) 
     std::cout << c->get() << std::endl; 

    for (std::vector<A*>::iterator i = v.begin(); i != v.end(); i++) 
     delete *i; 

    return 0; 
} 

Однако, я боюсь, что это код будет течь ... тем более, если я не хочу, чтобы пользователи явно удаляли содержимое вектора (они все равно его забудут), это должно произойти автоматически в конце main.

Есть ли другие решения? Я хотел использовать вектор std :: unique_ptr, но, видимо, они не работают таким образом ...

+2

«* Я хотел использовать вектор std :: unique_ptr, но, видимо, они не работают таким образом ... *« Пожалуйста, уточните. Кроме того, вы не пытаетесь «удалить» статически выделенные объекты (этот код не течет, как вы его предполагаете, но удаление объектов дважды вызывает UB). – ildjarn

+1

Поскольку вы работаете с статическими экземплярами: a) как этот код протекает и b) почему вы вызываете 'delete' на указатели, указывающие на статические объекты. В целом, я бы сказал, что ваш код (как вы показали нам) является ошибкой, но он не должен течь. – Grizzly

ответ

4
  1. Ваш код не просачивается. Единственное, что выделяет память, - std::vector, и оно очищает себя от разрушения.
  2. a и b правильно уничтожены и выпущены в конце выполнения.
  3. Вы не должны delete вещей, которые не были выделены new.

Кроме того, вы полагаетесь на v инициализируется перед тем a и b построены. Вам следует лениво инициализировать v (см. Ниже).

std::vector<A*>& global_v() 
{ 
    static std::vector<A*> v; 
    return v; 
} 

// use global_v() instead of v in the A constructor. 

Чтобы получить то, что вы хотите, просто удалите цикл, который удаляет эти объекты.

Here's ваш код работает в действии с удаленными циклами и добавлен некоторый отладочный вывод. Обратите внимание, что оба объекта уничтожены правильно.

+0

Удаление цикла, который удаляет эти объекты, получает только то, что он хочет, если это действительно все внутри одной единицы перевода - при условии, что настоящий проект с несколькими единицами перевода, нет никакой гарантии, что 'v' будет построен до того, как объекты попытаются вставить себя в него. – ildjarn

+0

Я думаю, он хочет, чтобы пользователи помещали 'new A' в вектор, но не заставляли пользователя «удалять» их. –

+0

@SethCarnegie: Где он это говорит? В первом предложении он говорит, что они будут статическими глобальными экземплярами. @ildjam: Верно, 'v' должен быть лениво инициализирован. Я добавлю это к моему ответу. –

Смежные вопросы