如何创建外部不可修改的变量
How to create externally unmodifiable variable?
我正在开发简单的模拟库,遇到了问题,其中我有模拟Time
变量,在任何情况下都不应该被API用户(程序员)修改(只提供有关模拟时间的信息),但应该可以通过模拟库修改,所以它不能是恒定的。
这就是我想出的,但对我来说似乎有点棘手
double simTime; // Internal time, modified by library
const double& Time = simTime; // Time info provided for programmer in API
有没有办法在没有const double&
的情况下解决这个问题?
您可以
更改 API 以提供返回 simTime
值的函数double getTime();
,而不是const double &
。
我发现const double&
解决方案相当直接和优雅,我没有看到任何负面的副作用。
唯一的问题是,您的库应该将simTime
声明为 static
或匿名命名空间中,以便无法从外部寻址。否则,任何其他翻译单元中的任何extern double simTime
都会暴露simTime
。
所以写...
// library.cpp:
static double simTime;
const double &simTimePublic = simTime;
// library.h:
extern const double &simTimePublic;
// userCode.cpp:
#include "library.h"
...
double simTimeCopy = simTimePublic;
// simTimePublic = 1.0; // illegal
您甚至可以(在公共标头中)定义一些内联函数,返回一个外部变量,其名称足够长,不容易被猜到,例如
static inline double getTime(void) {
extern double somelongname_simTime; // don't use that name directly
return somelongname_simTime;
}
事实上,名称somelongname_simTime
是公开的,但需要直接使用用户的恶意(因为它不是在公共头文件的文件范围内声明的)。
(你甚至可以使用namespace
技巧)
请注意,编译器无法阻止未定义的行为,例如指针意外获取static
变量的地址。
在Linux上,你甚至可以玩一些可见性技巧。
特别是对于 GCC,您可以尝试将两个名称用于相同的全局内存位置(使用汇编器标签),例如在您的公共标头中
extern volatile const double simTime_public asm ("myrealsimTime");
在某些实现文件中,您将拥有
double simTime_private asm("myrealsimTime");
当然,在玩这种技巧时,您是在滥用编译器和链接器。
(显然你可以混合使用这两种方法)。
相关文章:
- 如何从子成员函数修改父公共成员变量
- 修改程序的入口点时未调用全局变量的构造函数
- 为什么从另一个构造函数内部调用C++构造函数不修改类变量?
- 如何使用gmock模拟修改C++类中私有变量的成员函数
- 有了memory_order_relaxed,原子变量的总修改顺序如何在典型体系结构上得到保证
- 我们如何修改常量变量的值
- 是否可以禁止在for循环体内部修改循环变量
- 使用 QtConcurrent::run() 修改成员变量?
- 在 C++17 中修改 constexpr 函数中的全局变量
- 是否可以在不修改父类的情况下将成员变量初始化推迟到继承的类?
- 如何修改用户指定的变量?
- 打印/修改类对象的特定成员变量,其类定义列表 (STL) 包含的元素类型
- 在击中断点并继续执行VS时,如何在运行时自动修改变量的值
- C 如何使DLL从主线程修改变量
- 使用gcc插件修改变量声明的顺序
- 从子 DLL 访问/修改变量
- QThread:从不同线程修改变量的安全方法
- C++继承子类可修改变量
- 由于在序列点之间修改变量两次而导致的 UB 是否会转移到"inner"范围?
- assert()修改变量时发出警告