4

我正在开发简单的模拟库并遇到问题,我有模拟Time变量, API用户(程序员)在任何情况下都不应该修改它(只提供有关模拟时间的信息),但应该可以通过模拟库修改,所以它不可能是恒定的。

这是我想出的,但对我来说似乎有点棘手

double simTime;                // Internal time, modified by library
const double& Time = simTime;  // Time info provided for programmer in API

有没有办法解决这个问题const double&

4

3 回答 3

10

而不是const double &您可以更改您的 API 以提供一个double getTime();返回simTime.

于 2018-12-29T19:07:34.093 回答
5

我发现 - 解决const double&方案相当直接和优雅,而且我没有看到任何负面影响。

唯一的问题是您的库应该声明simTimestatic匿名命名空间或在匿名命名空间中声明,这样就无法从外部对其进行寻址。否则,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
于 2018-12-29T19:22:45.783 回答
1

您甚至可以(在公共标头中)定义一些返回外部变量的内联函数,该外部变量的名称足够长,不易被猜到,例如

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");

当然,在玩这些技巧时,您正在滥用编译器和链接器。

(显然你可以混合使用这两种方法)。

于 2018-12-31T16:21:03.330 回答