我正在开发一个仅包含头文件的库。到目前为止,它只包含类,一直很好。但是,我已经到了这样的程度,我需要在库中有一些库中可访问的不可变数据(即,不是类实例数据)来实现某些功能。你显然不能只将全局数据放在头文件中,或者#include
标题的每个编译单元都有符号的定义,你会在链接时得到多个定义错误。
我似乎找到了一种解决方法,它允许我在类中拥有静态数据,而无需通过在函数中将数据设为static
变量并返回指向该数据的指针来向库中添加编译单元数据:
class StaticData {
public:
void doSomething() { /* this uses getData */ }
void doSomethingElse() { /* this does too */ }
private:
static int* getData() {
static int array[] { 1, 2, 3, 4 };
return array;
}
};
这似乎工作正常,但我必须承认我不知道函数 - static
数据在头文件中的inline
函数会发生什么。我想知道这个“黑客”是否有任何意想不到的影响,例如每个编译单元#include
此标题获得自己的版本array
。编译器如何以及在何处决定使用它?
还应该注意的是,我没有使用它来实现单例反模式或任何东西。我只是用它来存储多个函数需要使用的数据(这就是为什么它只能在一个使用它的函数中static
,但即使它确实如此,也会提示相同的问题)
答案 0 :(得分:9)
没关系。只要该函数具有外部链接,就可以保证只有array
的一个副本。 C ++标准说:
7.1.2 / 4 extern内联函数中的静态局部变量始终引用同一个对象。
答案 1 :(得分:0)
另一种方法......
template<typename> class ArrayData {
friend class ClassWithArray;
static int array[4];
};
class ClassWithArray :
ArrayData<ClassWithArray>
{
public:
void doSomething() {
/* this uses getData */
array[0] = 1;
array[1] = 2;
array[2] = 3;
array[3] = 4;
}
void doSomethingElse() {
/* this does too */
array[0] = 4;
array[1] = 3;
array[2] = 2;
array[3] = 1;
}
};
int ArrayData<ClassWithArray>::array[4] = { 1, 2, 3, 4 };
通用实施
template<typename T> class ArrayDataT
{
friend T;
static int array[4];
};
template<typename T>
int ArrayDataT<T>::array[4] = { 1, 2, 3 ,4 };
class DerivedFromArrayDataT :
ArrayDataT<DerivedFromArrayDataT>
{
};