Дизайн класса для самосвязанных классов с общим типом указателя - PullRequest
3 голосов
/ 07 апреля 2011


В настоящее время я модифицирую сложный класс, в котором узлы указывают на себя , как связанные списки или графики. Я хочу, чтобы он использовался в общей памяти, используя функции boost :: interprocess . Сейчас я ищу способ перестроить его так, чтобы он оставался общим и содержал наименьшие изменения.

template< class T >  
class node {  
  public:  
    T data;  
    node* prev;  
    node* next;  
};

Редизайн должен использовать boost :: interprocess :: allocator allocator, чтобы неявно использовать относительные умные указатели типа boost :: interprocess :: offset_ptr . Я думал, что это должно включать второй параметр шаблона, как

template< class T, class alloc_type = std::allocator< node< T > > >  
class node {
  public:  
    T data;  
    typename alloc_type::pointer prev;  
    typename alloc_type::pointer next;  
};

который, конечно, не работает из-за циклических зависимостей, как со ссылками.
Я надеюсь, что вы можете получить некоторую помощь от шаблона класса C ++ pro, чтобы узнать, как лучше всего это реализовать. Я посмотрел на контейнеры с поддержкой расширенной совместно используемой памяти, но они решают ее довольно сложным образом, включающим несколько внешних классов.

Джох

Ответы [ 2 ]

1 голос
/ 07 апреля 2011

, что, конечно, не работает из-за циклических зависимостей, как со ссылками.

Да, это не будет работать, потому что тип node определен, и это не такеще не завершено, но вы передаете его allocator в качестве параметра типа.Отсюда проблема!

Кроме того, node - это шаблон класса, но когда вы передаете его в allocator, вы не предоставляете аргумент типа для node.Но не волнуйтесь, даже если вы пройдете, он не будет работать, так как тип node еще не завершен (как я уже говорил).


Кроме того, у вас есть другая проблема,

alloc_type::pointer prev;  
alloc_type::pointer next;  

Здесь вам нужно typename как

typename alloc_type::pointer prev;  
typename alloc_type::pointer next;  
0 голосов
/ 07 апреля 2011

Мне кажется, что класс распределителя принадлежит контейнеру, а не элементу. Я понимаю, что для таких навязчивых контейнеров они могут быть одинаковыми. Но можем ли мы вернуть это обратно?

Как насчет:

#include <memory>

template <class T, class alloc_type >
struct nodePtr {
    typedef typename alloc_type::pointer pointer;
    typedef alloc_type allocator;
};


template< class T >
class node {
  public:
    typedef nodePtr<node<T>, std::allocator<node<T> > > pointer;
    // OR: typedef nodePtr<node<T>, my_allocator<node<T> > > pointer;
    T data;
    pointer prev;
    pointer next;
};

node<int> n;

Конечно, я не могу понять, как передать std::allocator<> на node<>, но, возможно, вам это не нужно. Вы не возражаете, указав имя своего распределителя в середине class node?

Или, может быть, мы могли бы сделать ваш распределитель распределителем по умолчанию для nodePtr?

// untested
template <class T> class node;
template <class T, class alloc_type = my_allocator<node<T> > >
class nodePtr { /* ... */ };
template <class T> class node {
    public: typename nodePtr<T> prev;
}
...