Как создать внешне неизменяемую переменную?

Я занимаюсь разработкой простой библиотеки симуляции и столкнулся с проблемой, где у меня симуляция Time переменная, которая не должен быть модифицируемым пользователем API (программистом) при любых обстоятельствах (просто предоставить информацию о времени моделирования), но должен быть изменяемым по моделирующей библиотеке, поэтому она не может быть постоянной.

Это то, что я придумал, но мне это кажется немного сложным

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

Есть ли лучший подход для этого?

4

Решение

Вместо const double & Вы можете изменить свой API, чтобы обеспечить функцию double getTime(); который возвращает значение simTime,

10

Другие решения

Я нахожу 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
5

Вы могли бы даже (в публичном заголовке) определить некоторые в соответствии функция, возвращающая внешнюю переменную, имя которой достаточно длинное, чтобы ее нельзя было легко угадать, например,

static inline double getTime(void) {
extern double somelongname_simTime; // don't use that name directly
return somelongname_simTime;
}

действительно, имя somelongname_simTime является общедоступным, но требует непосредственного использования злого умысла (поскольку он не объявлен в области видимости файла в общедоступном заголовочном файле).

(и вы могли бы даже использовать namespace трюки)

Обратите внимание, что компилятор не может предотвратить неопределенное поведение, такое как указатель, случайно получающий адрес static переменная.

А в Linux вы могли бы даже поиграть в видимость трюки.


С НКУ конкретно Вы можете попытаться использовать два имени в одной и той же глобальной памяти (используя ассемблерные этикетки), например в вашем публичном заголовке

extern volatile const double simTime_public asm ("myrealsimTime");

и в некотором файле реализации вы будете иметь вместо

double simTime_private asm("myrealsimTime");

Конечно, вы злоупотребляете компилятором и компоновщиком, когда играете в такие трюки.

(и, очевидно, вы могли бы смешать оба подхода).

1