Контейнер без шаблонов, который может вместить что угодно - PullRequest
3 голосов
/ 08 августа 2011

У меня есть небольшой фреймворк для работы с потоками. Основная часть - это объект, который в основном управляется мьютексом std::queue, на который проталкивается один поток, а другой - на.

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

class Object {
public:
    Object(){}
    virtual ~Object(){}
};

Любой объект, который должен передаваться из потока в поток через этот класс, должен наследоваться от Object, поскольку это то, что содержит std::queue. Это хорошо работает, но я думаю, что должен быть лучший подход, так как этот подход требует наследования и много вызовов dynamic_cast. Есть идеи?

РЕДАКТИРОВАТЬ Указатели в этом случае также являются интеллектуальными указателями, поэтому важно сохранять информацию о типе.

Ответы [ 4 ]

6 голосов
/ 08 августа 2011

Использовать std :: queue <<a href="http://www.boost.org/doc/libs/1_47_0/doc/html/any.html" rel="nofollow"> boost :: any >. Он будет содержать объекты любого типа.

А чтобы получить объект, вы должны использовать специальную функцию приведения, предоставляемую самим бустом:

1 голос
/ 08 августа 2011

Вопрос в том, как типы могут варьироваться.Вы, конечно, должны иметь некоторые ограничения на то, что входит в контейнер.Почему предметы помещаются в контейнер?Основываясь на этом, вы должны быть в состоянии разработать разумный абстрактный базовый класс, который позволял бы использовать виртуальные функции для диспетчеризации, а не производные от искусственного Object без интерфейса.(В зависимости от назначения контейнера может потребоваться некоторый вариант шаблона посетителя. Таким образом, например, очередь сообщений может содержать виртуальную функцию processMessage( Base* ), чьи конкретные реализации ничего не делают, кроме как вызывают различные функции-члены Base.)

1 голос
/ 08 августа 2011

Возможно, вы захотите заглянуть в boost :: any , если хотите быть более безопасным.

1 голос
/ 08 августа 2011

Используйте void* в вашем контейнере для «указателя на неизвестный тип» (или const void*, если объекты неизменны). Он по-прежнему требует приведения (и, следовательно, информацию о типе из другого бокового канала), но у вас действительно нет других вариантов, если вы хотите избежать шаблонов и наследования.

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