2009-09-30 6 views
0

У меня есть большой набор классов, которые мне нужно «обернуть» в очень тонком подклассе. Функциональность базовых классов не меняется, и их интерфейс остается неповрежденным.Дублирование конструкторов базового класса в подкласс?

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

Что это самый простой способ сделать это?

Редактировать: Даже если это не поддерживается на языке, возможно, есть инструмент, который может автоматически генерировать этот код?

+0

Пример кода может помочь. Вы делаете что-то вроде 'Subclass(): BaseClass (params) {}'? –

+0

@ Ник: Да. 'subclass (param1, param2, param3): baseclass (param1, param2, param3) {}' – sold

ответ

2

Вы можете добавить шаблонного конструкторами для всех возможных параметров в класс обертку:

template<class Base> 
class wrapper : public Base { 
public: 
    wrapper() : Base() {} 

    template<typename T1> 
    wrapper(T1 a1) : Base(a1) {} 

    template<typename T1, typename T2> 
    wrapper(T1 a1, T2 a2) : Base(a1, a2) {} 

    // ... 
}; 

Поскольку шаблоны не будут создаваться для конструкторов, которые не называют это не имеет значения, если эти другие конструкторы бы инвалид. Только конструкторы, которые фактически используется должны существовать в базовом классе:

class A { 
public: 
    A(int a) {}; 
}; 

int main() { 
    wrapper<A> aw(1); 
    return 0; 
} 

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

0

Желаемое заставляет меня предположить

class BaseClass { 
public: 
    BaseClass(foo, bar, baz); 
}; 

template <class T> 
class BaseInheritor : public BaseClass { 
public: 
    T(foor, bar, baz); 
}; 

class Child : public BaseInheritor<Child> { 
    // Other stuff 
}; 

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

#define CHILD_CLASS_DEFAULT(name) \ 
class name : public BaseClass { \ 
    public: name(foo, bar, baz) : BaseClass(foo, bar, baz) { } \ 
    private: 


#define CHILD_CLASS_OVERRIDE(name) \ 
class name : public BaseClass { \ 
+0

Этого не будет, потому что существует множество базовых классов, у каждого из которых есть другой набор конструкторов (с разными параметрами). – sold

+0

Это заставляет меня думать о трюках с участием 2 или 3 макроопределений в базовом классе и некоторых меток. Это было бы очень уродливо. – Novelocrat

0

Я бы для решения на основе сценариев, возможно, на основе gccxml или что-то подобное.
С этим вы можете написать простой скрипт (т. Е. generate-derivate <input-file> <base-name> <derivative-name> <output-file>), который генерирует вам обертку. Если вы добавляете/меняете функциональность, вам нужно внести изменения вручную.

редактировать: расплывчатый контур:

write derivative-name + " : public " + base-name + " {\npublic:\n" 
foreach <Constructor> where attribute name == base-name 
    write "\tderivate-name(" 
    foreach <Argument> 
     resolve by attribute type (query FundamentalType, ReferenceType, ...) 
     write argument type etc. 
    write ");\n" 
write "\n};\n" 

Все зависит от того, что скрипт языка и что XML-инструменты, которые вы используете. Trolltech имеет XQuerys в their example.

+0

Это похоже на решение. Однако я никогда не использовал gccxml. можете ли вы дать схему для такого сценария? – sold

+0

Я добавил его к ответу. –

Смежные вопросы