C++ 我可以修改常量成员变量吗?

C++ 我可以修改常量成员变量吗?,c++,constants,C++,Constants,我知道,我知道。问题只是尖叫“你不应该处于那种情况!”但请听我说完 我有一个游戏引擎,在一个线程中执行更新,在另一个线程中执行渲染。渲染希望从上一帧读取数据,而更新将更新下一帧的数据 所以,为了解决这个问题,我有一个POD结构,可变的_数据,就是物体中可以改变的一切(速度,位置等等),我在物体内部有两个实例,一个是常数,另一个不是常数。在游戏循环的一次迭代结束时,非常量数据将是最新的数据对象,然后我想将其复制到常量实例上,以便它们现在相等,并为下一次迭代做好准备 这可能吗 我已经起草了一个示例程

我知道,我知道。问题只是尖叫“你不应该处于那种情况!”但请听我说完

我有一个游戏引擎,在一个线程中执行更新,在另一个线程中执行渲染。渲染希望从上一帧读取数据,而更新将更新下一帧的数据

所以,为了解决这个问题,我有一个POD结构,可变的_数据,就是物体中可以改变的一切(速度,位置等等),我在物体内部有两个实例,一个是常数,另一个不是常数。在游戏循环的一次迭代结束时,非常量数据将是最新的数据对象,然后我想将其复制到常量实例上,以便它们现在相等,并为下一次迭代做好准备

这可能吗

我已经起草了一个示例程序,希望能清楚地说明我的意思:

#include <iostream>

struct mutable_data
{
  int i = 1;
  bool j = true;
  char k = 'a';
};

struct my_data
{
  my_data() : constData() {} 

  int i() const { return constData.i; }
  bool j() const { return constData.j; }
  char k() const { return constData.k; }

  void set_i(int i) { data.i = i; }
  void set_j(bool j) { data.j = j; }
  void set_k(char k) { data.k = k; }

  void update() { constData = data; }

private:
  mutable_data const constData;
  mutable_data data;
};

int main()
{
  my_data d;
  std::cout << "i: " << d.i() << ", j: " << d.j() << ", k: " << d.k() << std::endl;

  d.set_i(10);
  d.set_j(false);
  d.set_k('z');

  std::cout << "i: " << d.i() << ", j: " << d.j() << ", k: " << d.k() << std::endl;
  std::cout << "===============" << std::endl;

  d.update();

  std::cout << "i: " << d.i() << ", j: " << d.j() << ", k: " << d.k() << std::endl;
}
#包括
结构可变_数据
{
int i=1;
bool j=真;
字符k='a';
};
结构我的_数据
{
my_data():constData(){}
int i()常量{return constData.i;}
bool j()常量{return constData.j;}
char k()常量{return constData.k;}
无效集_i(int i){data.i=i;}
无效集_j(bool j){data.j=j;}
无效集_k(char k){data.k=k;}
void update(){constData=data;}
私人:
可变_数据常量constData;
可变_数据;
};
int main()
{
我的大学数据;

std::cout对两个数据结构使用访问器,一个用于当前(const),另一个用于即将到来的数据结构

mutable_data & currentData() { return *currentPtr; }
const mutable_data & upcomingData() { return *upcomingPtr; }

void update() { std::swap(currentPtr, upcomingPtr); }

对两个数据结构使用访问器,一个用于当前(const),另一个用于下一个

mutable_data & currentData() { return *currentPtr; }
const mutable_data & upcomingData() { return *upcomingPtr; }

void update() { std::swap(currentPtr, upcomingPtr); }

这是一个非常有趣的问题,我想你得到的是在适合并发的条件下实现的问题

正如在另一篇文章中所讨论的,一种可能的方法是将变量修改为
mutable

当然,为了达到这一目的,必须重新设计结构。使用
const
方法初始化所述变量将使您能够锁定所需的值


除了关键字
mutable
,您还应该考虑使用
const\u cast
来重铸变量。

这是一个非常有趣的问题。我认为您得到的是在适合并发的条件下实现时的问题

正如在另一篇文章中所讨论的,一种可能的方法是将变量修改为
mutable

当然,为了达到这一目的,必须重新设计结构。使用
const
方法初始化所述变量将使您能够锁定所需的值


除了关键字
mutable
,您还应该考虑使用
const\u cast
来重铸您的变量。

为什么const one标记为const,如果它不是为了保持常量的话?请评论一下您的数据结构:保留两个独立的数据树,并使用顶级指针交换以进行更新不是更好吗d代表读取?而不是在每个对象中保留两组数据。@Adam,因为它是一个常量对象。我不希望任何东西玩它…除非它需要更新。我知道我可以声明它不是常量,但在这种情况下,它是常量更合适。不?然后更新可能看起来像
update->obj[index].position=read->obj[index].position+read->obj[index].delta
或类似内容。@Sam:“因为它是一个常量对象。我不想让任何东西玩它……除非它需要更新”--您永远不希望任何对象被修改,除非它应该被修改。这并不意味着每个对象都应该是
const
;-)
constData
是其类的私有成员,并且类中唯一修改它的代码在
update()
中。这足以强制执行仅
update()的约束
修改它。如果您的类很小且集中,那么您无意中编写代码在其他地方修改它不会有实际危险。如果const one不是为了保持常量,为什么它会被标记为const?请评论您的数据结构:保留两个独立的数据树,并使用顶级指针交换ch代表更新,哪个代表读取?而不是在每个对象中保留两组数据。@Adam,因为它是一个常量对象。我不希望任何东西玩它…除非它需要更新。我知道我可以声明它不是常量,但在这种情况下,它更适合于常量。不?然后更新可能会发生看起来像
update->obj[index].position=read->obj[index].position+read->obj[index].delta
或类似的东西。@Sam:“因为它是一个常量对象。我不想让任何东西玩它……除非它需要更新”--您永远不希望任何对象被修改,除非它应该被修改。这并不意味着每个对象都应该是
const
;-)
constData
是其类的私有成员,并且类中唯一修改它的代码在
update()
中。这足以强制执行仅
update()的约束
修改它。如果您的类很小且集中,那么您无意中编写代码在其他地方修改它不会有实际危险。交换不起作用,我不认为……它不一定是副本吗?假设currentData在第10帧上,upcomingData现在在第11帧上。因此,当您交换时,Coming返回到第10帧,而我们'在第11帧上,第12帧的数据即将写入,即使第11帧的数据不在那里。这有意义吗?抱歉,我发现很难解释这一点!:)@Sam如果你愿意,你也可以复制,你没有显示足够的逻辑来知道是否有必要。关键是两个指针都不是