1

我正在派生一个可从 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

4 回答 4

5

您有一个“来自成员初始化的基础”的案例。

一个解决方案。

于 2010-09-28T09:07:52.673 回答
1

撇开 Hacky 注入代码不谈,我认为这样做的合理方法是使用“has a”而不是“is a”模式:只需在您自己的类中拥有一个库类的实例。这样您就可以随心所欲地控制分配和解除分配顺序。

于 2010-09-28T09:10:06.317 回答
1

您对一个参数构造函数的解决方案并不真正有用,因为它仍然无法访问正在构造的类(因为它还没有发生)并且不清楚如何使用这种 hacky 形式完成任何有用的事情(除了可能设置影响基本 ctor 的全局范围值)。

Stephan 提出的解决方案如下所示:

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 的构造函数,该函数在返回使用私有构造函数创建的实例化对象之前运行注入,但从您的问题看来,这不适合您的上下文。

于 2010-09-28T09:21:37.013 回答
0

为什么不能再添加一层?

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"); }
};
于 2010-09-28T09:03:09.703 回答