我在工作中看到了这个,它是我加入之前由人们写的。使用静态变量代替类的静态成员。就目前而言,我看不出为什么不应在此处使用类的静态成员的原因。如果我想说服这里的人们改变它,是否有什么好的借口说服他们?
我试图找到静态成员和静态变量之间的区别,似乎除非有充分的理由,否则人们总是倾向于使用静态成员,但没有提到非常现实的情况。
当前代码:
ListAdapter
此功能的使用方式:
class Foo {
public:
static Foo *get() {
static Foo _instance;
return &_instance;
}
// ...
};
我想到的代码应如何定义类:
int XXX_loadxxx(const char xxx, foo_handle *handle) {
// just get foo ptr and return
xxx::foo *ptr = xxx::foo::get();
int ret = ptr->init();
if (ret != 0) {
return -1;
}
*handle = ptr;
return 0;
}
如果有人能告诉我将其更改为静态成员是否有任何不同,以及原因,我将非常感谢。
答案 0 :(得分:5)
第一种解决方案更好,原因有二:
get()
时会初始化静态单例,这意味着您具有可预测的行为,不同翻译单元上的static
变量则不是这种情况我不明白为什么您希望从方法中将其解封装。
答案 1 :(得分:2)
与静态局部变量相比,静态成员变量(以及命名空间范围内的静态变量)有一些缺点:
1 甚至在首次使用构造时,仍然存在一种复杂的违反顺序保证的方法:如果存在静态对象A,其构造函数不依赖于静态对象B,但是A的析构函数确实取决于B,那么B仍然可能首先被破坏,从而导致UB。如果A的任何部分依赖于B,则始终通过在A的构造函数中调用B的静态获取器可以避免这种情况。通常,由于这些问题,应避免使用静态对象。
P.S。通常,您希望从getter返回一个引用,以便调用者不必担心获取null。
P.P.S。 static Foo_instance;
应该是static Foo instance;
P.P.P.S。使用静态成员时,吸气剂大部分变成 2 无效;成员可以改为公开。
2 如果您打算使用继承来扩展静态对象,同时又保持与原始接口的兼容性,那么它可能仍有一些价值。
答案 2 :(得分:2)
两个示例都无法编译。 static Foo_instance
是什么意思?您是说static Foo instance
吗?
现在回到您的问题:如果您在函数内部定义了静态变量,则只有在您首次调用该函数时才会对其进行初始化。有两个后果:
答案 3 :(得分:0)
在并发环境中,本地静态可变初始化是安全的。
另一个优点是,在调用相应函数的情况下,将其初始化为onlt。那就是该变量被请求初始化。
根据C ++ 17标准
4使用静态存储动态初始化块范围变量 持续时间(6.6.4.1)或线程存储持续时间(6.6.4.2) 控件第一次通过其声明;这样的变量 在初始化完成后被视为已初始化。 如果初始化因抛出异常而退出,则 初始化未完成,因此下一次将再次尝试 时间控制进入声明。 如果控件进入 在初始化变量的同时声明 并发执行应等待完成 。如果控件递归地重新输入声明 在初始化变量时,行为未定义