Дизайн для использования всех подклассов вместе в контейнере в C ++ - PullRequest
2 голосов
/ 29 июля 2010

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

Например:

template<class T>
struct A
{
    void func() { static_cast<T*>(this)->func(); }
};

struct B : public A<B>
{
    void func() { cout << "B" << endl; }
};`

Однако, если у нас много подклассов из A и мы хотим поместить их все в вектор, напримерvector<A*> это невозможно, когда вы используете шаблоны, и вам приходится использовать обычный полиморфизм с виртуальными функциями в базовом классе.

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

Ответы [ 3 ]

5 голосов
/ 29 июля 2010

Вы можете сделать это:

class NonTemplateBase
{
};

template<class T>
struct A : public NonTemplateBase
{
    void func() { static_cast<T*>(this)->func(); }
};

и затем создать вектор указателей на NonTemplateBase (т.е. std::vector<NonTemplateBase *>).

Однако, я предполагаю, что вы хотитебыть в состоянии вызвать func() или другие функции-члены для объектов в вашем векторе - и вы хотите, чтобы эти вызовы полиморфно вызывали правильную функцию-член в производном классе.

Это не сработает, потому чтошаблон любопытно повторяющегося шаблона позволяет вам только статический (т.е. во время компиляции) полиморфизм.Если вы хотите полиморфизм во время выполнения, вы должны использовать виртуальные функции.

1 голос
/ 29 июля 2010

Определите не шаблонный абстрактный базовый класс для вашего шаблонного класса. Используйте базовый класс для работы с контейнерами.

0 голосов
/ 29 июля 2010

Пусть все ваши шаблоны реализуют общий интерфейс и создают вектор указателей или ссылок на этот интерфейс.

class Icommon //interface
{
public:
    virtual void print() = 0;
};

template <class T>
class MyCommon : public Icommon
{
    T obj;

public:
    MyCommon(T o):obj(o) {}

    void print() {cout << obj;}
};

main()
{
    MyCommon<int> i(1);
    MyCommon<char> c('t');

    vector<Icommon *> commonVec;

    commonVec.push_back(&i);
    commonVec.push_back(&c);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...