Внедрение кода в конструктор базового класса C ++ - PullRequest
1 голос
/ 28 сентября 2010

Я извлекаю класс, который доступен из библиотеки C ++, и конструктор моего подкласса будет работать правильно только тогда, когда я выполню некоторый код до того, как будет вызван конструктор базового класса.(Да, я знаю, плохой дизайн, но я не могу повлиять на работу библиотеки, которую я использую.)

Если конструктор базового класса принимает аргументы, сделать это на самом деле довольно просто:

struct A {
    A(bool a) { printf("A::A()\n"); }
};

bool inject(bool a) { printf("inject()\n"); return a; }

struct B : public A {
    B(bool a) : A(inject(a)) { printf("B::B()\n"); }
};

Теперь, когда я создаю экземпляр B, inject() вызывается до A::A().Но есть ли способ сделать это, когда базовый класс ctor не имеет аргументов?

Ответы [ 4 ]

5 голосов
/ 28 сентября 2010

У вас есть случай "База из инициализации члена".

Решение есть там .

1 голос
/ 28 сентября 2010

Ваше решение для конструктора с одним параметром не кажется действительно полезным в том смысле, что оно все еще не может получить доступ к создаваемому классу (как это еще не происходит), и неясно, как что-либо полезное можно сделать с помощью этого хакера.form (за исключением, возможно, установки глобальных значений области видимости, которые влияют на базовый ctor).

Предлагаемое решение Стефана будет выглядеть примерно так:

struct A {
    A() { printf("A::A()\n"); }
};

struct Injector {
  Injector() { printf("inject()\n"); } 
}

struct B : public A,private Injector {
    B() : Injector(), A() { printf("B::B()\n"); }
};

Это нормальное решение, но кажется немного неуклюжиммне.Другое возможное решение - использовать статическую функцию класса вместо конструктора для B, который запускает инъекцию перед возвратом экземпляра объекта, созданного с помощью частного конструктора, но из вашего вопроса видно, что это не соответствует вашему контексту.

1 голос
/ 28 сентября 2010

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

0 голосов
/ 28 сентября 2010

Почему вы не можете добавить еще один слой?

struct A {
    A(bool a) { printf("A::A()\n"); }
    A();
};

struct A_Wrap : public A {
    A_Wrap(bool ) : A() { } ;
};

bool inject(bool a) { printf("inject()\n"); return a; }

struct B : public A_Wrap {
    B(bool a) : A_Wrap(inject(a)) { printf("B::B()\n"); }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...