gpt4 book ai didi

具有静态成员的 C++ 寄存器模式有效 "sometimes"

转载 作者:行者123 更新时间:2023-11-30 03:45:01 25 4
gpt4 key购买 nike

我正在尝试在运行时实现自动类注册(我认为这种技术属于“注册模式”的名称)。在下面的示例中,我将 int 存储在静态成员 vector 中,但目标是存储以后可以调用的函数指针。
我的理解是,由于我下面代码中的成员registeredClasses被声明为static,所以在整个程序中应该只有一个它的实例。然而,情况似乎并非如此:

类寄存器.h

#ifndef CLASSREGISTER_H
#define CLASSREGISTER_H

#include <vector>
#include <iostream>

class ClassRegister
{
public:
static std::vector<int> registeredClasses; //declaration

ClassRegister(int id) {
std::cerr << "registering " << id << " ";
registeredClasses.push_back(id);
std::cerr << "new size: " << registeredClasses.size() << "\n";
}

//code below just for testing
ClassRegister() {}

static int getSize() {
return registeredClasses.size();
}
};

#define REGISTER_CLASS(cls) \
static ClassRegister myClass_##cls(1);

#endif // CLASSREGISTER_H

类注册.cpp

#include "classregister.h"

std::vector<int> ClassRegister::registeredClasses; //definition

class1.h(class2.h遵循相同的模式,为简洁起见省略)

#ifndef CLASS1_H
#define CLASS1_H

#include "classregister.h"

class Class1
{
public:
Class1();
};

REGISTER_CLASS(Class1)

#endif // CLASS1_H

class1.cpp(class2.cpp遵循相同的模式,为简洁起见省略)

#include "class1.h"

Class1::Class1()
{
}

主要.cpp

#include "classregister.h"
#include <iostream>

int main(int argc, char *argv[])
{
std::cerr << "registering classes works...\n\n";

std::cerr << "but reading from main() does not...\n";
std::cerr << "checking size directly: " << ClassRegister::registeredClasses.size() << "\n";
std::cerr << "checking size through function: " << ClassRegister::getSize() << "\n";
std::cerr << "checking size on instance: " << ClassRegister().getSize() << "\n";
std::cerr << "\n";

std::cerr << "registration from main() uses a different register...\n";
ClassRegister(2);
ClassRegister(3);
ClassRegister(4);
std::cerr << "\n";

std::cerr << "...which is not the one used in the header files\n";
std::cerr << "checking size directly: " << ClassRegister::registeredClasses.size() << "\n";
std::cerr << "checking size on instance: " << ClassRegister().getSize() << "\n";
std::cerr << "checking size through function: " << ClassRegister::getSize() << "\n";
std::cerr << "\n";
}

我遇到的问题是它仅“有时”有效。初始输出:

registering 1 new size: 1
registering 1 new size: 2
registering classes works...

but reading from main() does not...
checking size directly: 0
checking size through function: 0
checking size on instance: 0

registration from main() uses a different register...
registering 2 new size: 1
registering 3 new size: 2
registering 4 new size: 3

...which is not the one used in the header files
checking size directly: 3
checking size on instance: 3
checking size through function: 3

我删除了 class1.cpp 和 class2.cpp,在头文件中声明了构造函数,例如。 Class1() {}。注册根本不起作用:

//no output here
registering classes works...
//...

然后我恢复了更改,突然我得到了预期的输出:

registering 1 new size: 1
registering 1 new size: 2
registering classes works...

but reading from main() does not... //it does work this time
checking size directly: 2
checking size through function: 2
checking size on instance: 2

registration from main() uses a different register...
registering 2 new size: 3
registering 3 new size: 4
registering 4 new size: 5

...which is not the one used in the header files
checking size directly: 5
checking size on instance: 5
checking size through function: 5

我一直在研究这个问题,但未能弄清楚原因。我的猜测是它与编译顺序有关(但注册如何工作?)或与 linkage 有关。/storage duration .有人可以阐明这一点吗?

最佳答案

我认为您在这里需要的技巧是在 ClassRegister 中而不是静态数据成员中,使用具有静态本地的函数。这有时被称为单例,虽然我不知道这是否真的是正确的术语。

代码可能如下所示:

typedef std::vector<int> register_type;
register_type& getRegister() {
static register_type registeredClasses; //declaration
return registeredClasses;
}

关于具有静态成员的 C++ 寄存器模式有效 "sometimes",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35094850/

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