Дублирование конструкторов базового класса на подкласс? - PullRequest
0 голосов
/ 01 октября 2009

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

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

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

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

Ответы [ 4 ]

2 голосов
/ 01 октября 2009

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

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;
}

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

1 голос
/ 01 октября 2009

Я думаю, что вам не повезло, если вы не можете использовать C ++ 0x. Прочитайте эту статью:

Автоматическое создание конструктора на основе конструктора родительского класса (C ++)

0 голосов
/ 01 октября 2009

Я бы выбрал решение на основе сценариев, возможно, на основе 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 в их примере .

0 голосов
/ 01 октября 2009

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

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 { \
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...