Надлежащее использование shared_ptr? - PullRequest
8 голосов
/ 15 апреля 2011

Без опыта работы с shared_ptr<> Мне интересно, является ли следующее подходящим вариантом использования, а также является ли хорошей идеей возвращать shared_ptr<> пользователю.

У меня есть графоподобная структура с несколькими связями между узлами. Во время обхода графика каждому узлу присваивается значение (вычисляется из подключенных узлов), и я хочу, чтобы пользователь мог легко получить доступ к значению. Все выглядит (сильно упрощенно) так:

class Pool;
class Node {
    public:
        typedef std::tr1::shared_ptr<Node> Ptr;  
        ...
        void compute_dependencies() { 
            ...
            // calls Pool to get a new Node instance
            dependencies_.push_back(Pool::create_node(...));
            ...
        }

        // evaluate the current node
        void evaluate() { /* use dependencies_ */ };        
        double value() const { if(evaluated) return value_; };

    private:
        std::vector<Node::Ptr> dependencies_;            // vector<Node*> better?
        dbl value_;
}

// Pool creates and owns all nodes
class Pool {
    public:
        static const Node::Ptr create_node(...);         // create a new node
        void traverse_and_evaluate();      

    private:
        std::vector<Node::Ptr> allnodes;   // appropriately sorted to ensure 
                                           // dependencies are evaluated 
        ...
}

и пользователь звонит:

Pool pool();
Node::Ptr node1 = Pool::create_node(...);
Node::Ptr node2 = Pool::create_node(...);
....
pool.traverse_and_evaluate();   
// ready to read out the now populated values
cout << node1->value() << " " << node2->value() << ... 

Преимущество этого заключается в том, что пользователь получает прямой доступ к интересующим его узлам (зависимости часто неинтересны). Но я не уверен на 100%, хорошая ли это идея.

Спасибо за ваш вклад!

Редактировать: круговых зависимостей нет.

Ответы [ 2 ]

10 голосов
/ 15 апреля 2011

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

Когда у вас есть явный владелец, такой как ваш класс Pool, иNode объектам не нужно переживать владение Pool, тогда действительно нет нужды в shared_ptr.Вы можете просто уничтожить объекты в деструкторе владельца.

3 голосов
/ 15 апреля 2011

Я хотел бы предоставить доступ к другим пользователям с помощью weak_ptr. Вы можете создать weak_ptr непосредственно из shared_ptr .

Пользователь обычно получает слабый_птр из пула, а затем создает shared_ptr from weak_ptr .lock ().

Это сообщает пользователю, что у него нет прав собственности, и следует соблюдать осторожность, чтобы не поддерживать блокировку дольше, чем необходимо - или, по крайней мере,это для меня:)

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