我正在编写一些使用其他库中的类型和函数的类。在调用任何其他函数之前,此库需要初始化。此外,类使用库提供的数据类型,在使用之前也必须初始化(但在初始化库之后)。这些类如下所示:
class A {
public:
A() { init(); }
void init() { lib_type_init(&t); }
// ...
// Other methods
// ...
protected:
lib_type t;
// ...
// Other fields
// ...
}
我不想在init()
的实例上显式调用A
,因为我的应用程序中有很多A
的实例,所以我打电话给{{1}在构造函数中。但是,当我想在全局范围内定义init()
的实例时,这会出现问题。所以我认为继承是正确的答案,只是提供一个构造函数,它不会调用A
并要求应用程序在使用全局实例之前显式调用init()
。例如:
init()
但是,这仍然是一个问题,因为在C ++中,如果构造函数没有参数,则基类构造函数由派生类调用。当调用对象的全局构造函数时,这显然会在运行时导致问题(它试图调用库init函数并因为库本身未初始化而产生错误)。
这些类有相对大量的方法,我不希望我的代码大小爆炸。有了这个说法,除了完全复制class global_A : public A {
public:
global_A() {}
}
到A
没有构造函数之外,还有更好的解决方法吗?
答案 0 :(得分:2)
默认构造函数似乎总是自动调用init()
。如果有其他构造函数不调用init()
,那么只有公共init()
函数才有意义。您应该从派生类的成员初始化列表中调用相应的构造函数:
global_A::global_A(): A(some_arguments) {}
另一种方法可能是使用返回引用的函数本地对象,并在初始化库之后的适当时间调用此函数:
global_A& global() {
static global_A rc;
return rc;
}
除此之外,不是说你可能最好不要**首先没有任何全球物品!通常,任何全局状态都会使代码难以测试,并在涉及并发时导致问题。
答案 1 :(得分:1)
听起来A
应该继承global_A
,而不是相反。
虽然,您可能想要一个比global_A
更好的名称。
答案 2 :(得分:0)
在基类上创建一个不调用init()的非默认构造函数。在全局类的构造函数的初始化列表中显式调用此非默认构造函数。