Переупорядочение шаблонных функций C ++ - PullRequest
0 голосов
/ 13 июня 2010

В C ++ у меня есть определенная функция шаблона, которая при заданном условии вызывает функцию шаблона в другом классе.Проблема заключается в том, что другому классу требуется полное определение первого класса, поскольку он создает второй класс и сохраняет их и управляет ими аналогичным образом.

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

Любой совет, как это можно реализовать?

Edit @ comment: у меня проблема, которая выглядит немногоthis:

class Master {
public:
    Child* CreateChild() {
        return new Child();
    }
    template<typename T> T* GetSomething(int arg) {
        return NULL;
    }
};
class Child {
    Master* master;
    template<typename T> T* GetSomething(int arg) {
        if (arg) return master->GetSomething<T>(arg);
        else return NULL;
    }
};

Это, очевидно, не фактические реализации, но достаточно похожие для демонстрации.PIMPL поможет, только если это не шаблонные функции, но так как они есть, то IMPL должен быть прямо здесь.

Мастер-класс управляет всеми детьми (почему я выбрал Master и Child вместо Parent/ Ребенок или Мастер / Раб?), Их память, время жизни и т. Д., И некоторые другие общесистемные потребности.Но класс Child обеспечивает большую часть доступа, и в некоторых случаях он должен возвращаться к мастер-классу.

Кроме того, в аду нет никакой возможности перейти к динамическим привязкам.Остальная часть моей системы уже полностью злоупотребляет динамическими привязками до абсолютного максимума, и я просто не могу позволить себе использовать их снова таким образом.Рассматриваемая функция Child вызывается очень, очень, очень часто.

Ответы [ 3 ]

2 голосов
/ 13 июня 2010

Для вашего примера тот факт, что классы имеют функцию шаблона, не имеет никакого значения;просто получите прямую ссылку на класс Child и поместите определение функции CreateChild после объявления класса Child:

class Child;
class Master {
public:
    Child* CreateChild() ;
    template<typename T> T* GetSomething(int arg) {
        return NULL;
    }
};

class Child {
public:

    Master* master;
    template<typename T> T* GetSomething(int arg) {
        if (arg) return master->GetSomething<T>(arg);
        else return NULL;
    }
};

Child* Master::CreateChild() {
    return new Child();
}
1 голос
/ 13 июня 2010

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

Child.h: Не включать Parent.h,вместо этого используйте предварительное объявление (пример: class Parent;).Затем вы можете определить функции, которые принимают или возвращают только родительские указатели (без ссылок или экземпляров).Вы не можете вызывать какие-либо Parent функции-члены или обращаться к переменным-членам внутри заголовка.

Parent.h: Включить Child.h как обычно.Никаких ограничений на использование объектов Parent или Child в этом файле.

Parent.cpp и Child.cpp: включите Child.h и Parent.h как обычно.Никаких ограничений на использование родительских или дочерних объектов в этих файлах.

0 голосов
/ 13 июня 2010

Краткий ответ: «Перейти к динамическим привязкам».

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

...