gpt4 book ai didi

c++ - C++ 中的可扩展自动类注册

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:46:16 29 4
gpt4 key购买 nike

C++ 中的自动类注册是一项常见任务,也是 StackOverflow 上的一个常见问题:

Register an object creator in object factory

Somehow register my classes in a list

automatic registration of object creator function with a macro

c++ automatic factory registration of derived types

基本目标是通过一些注册表或工厂自动注册类,以便稍后可以对每个类做一些工作。

这是一项成熟的技术,被(例如)Google Test (http://code.google.com/p/googletest) 等库使用,它会自动注册 Test 类的子类,以便每个测试都可以自动实例化并在测试执行期间运行。

注册可以通过实例化一个由其构造函数进行注册的静态 Registrar 类来完成,或者巧妙地使用 CRTP 并将注册代码放入基类构造函数中,或者任何您喜欢的方法(上面的链接提供了几种不同的可能技术).

但是,当我实现这些技术中的任何一种时,我发现它们的扩展性非常差。如果我在 Google Test 中调用了 10,000 次 TEST 宏,编译和链接就会停​​止(MSVC 2010)并且二进制文件大小会爆炸。如果我以另一种方式实现它,使用 10,000 个子类和静态注册器,我会看到相同的行为。

例如,考虑简化的例子:

#include <iostream>
#include <string>

class Base {

public:

Base( const std::string& Name_ ) : Name( Name_ ) { ; }
~Base() { ; }

virtual std::string GetName() const { return Name; }
virtual void DoSomething() = 0;

private:

std::string Name;

};

class Registry {

public:

static Registry& GetInstance() {
static Registry* Instance = new Registry();
return *Instance;
}

void Register( const Base* b ) {
std::cout << "Registered class " << b->GetName() << std::endl;
}

private:

Registry() { ; }
~Registry() { ; }

};

class Registrar {

public:

Registrar( const Base* b ) {
Registry::GetInstance().Register( b );
}

~Registrar() { }

};


#define REGISTER( CLASS ) \
class CLASS : public Base { \
public: \
CLASS( const std::string& Name ) : Base( Name ) { ; } \
virtual void DoSomething(); \
private: \
static Registrar m_Registrar; \
}; \
Registrar CLASS::m_Registrar( new CLASS( #CLASS ) ); \
void CLASS::DoSomething()


int main( int argc, char** argv )
{
return 0;
}


REGISTER( Class1 )
{
std::cout << "Doing something in Class1" << std::endl;
}

REGISTER( Class2 )
{
std::cout << "Doing something in Class2" << std::endl;
}

[...]

总共有 10000 个自动生成的 REGISTER 调用。

这是否有无法很好扩展的根本原因?编译器会因为 10000 个类而窒息吗?在 MSVC 2010 下,在相当快的机器上编译上述内容需要将近两分钟,并生成大小超过 5 MB 的二进制文件。如果我对 Google Test 进行类似操作,我会看到相同的结果。

最佳答案

用 C++ 编写 Java 代码很少能奏效。所有这些堆分配可能会降低性能(就像在 Java 中一样,但 Java 启动速度太慢以至于没有人会注意到)。使用静态对象,不要在每个生成的类中都放入一个Registrar对象;那只是浪费时间和空间。

关于c++ - C++ 中的可扩展自动类注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13824375/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com