2014-01-30 54 views
0

我知道,我知道。这个问题只是尖叫“你不应该在这种情况下!”但听我说...我可以修改一个const成员变量吗?

我有一个游戏引擎,执行更新在一个线程和渲染在另一个。渲染器想要从前一帧读取数据,而更新会像下一帧一样更新数据。因此,为了解决这个问题,我有一个POD结构体mutable_data,它是对象中可以改变的所有东西(速度,位置等等),我在对象中有两个实例,一个是const,而另一个是const其他不是。在游戏循环的一次迭代结束时,非常量数据将成为最新的数据对象,然后我想将它复制到常量实例上,以使它们现在相等并准备好进行下一次迭代。

这可能吗?

我已经起草了一个例子程序,希望清楚我的意思:

#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; 
} 
+4

为什么const表示常量,如果它不是保持不变? – Adam

+0

对你的数据结构的评论:保持两个独立的数据树与最高级别的指针交换哪个是更新和哪些是用于读取是否更好?而不是在每个对象内部保存两组数据。 –

+0

@Adam因为它是一个const对象。我不想要任何东西玩它,除非它需要更新。我知道我可以只声明它不是const,但在这种情况下,感觉它更适合于const。没有? –

回答

4

您的两个数据结构,一个用于电流(常量)之一,另一个是即将到来的一个使用存取。

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

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

交换不起作用我不认为......它不一定是副本吗?假设currentData在第10帧,即将到来的数据现在在第11帧。所以,当你交换时,即将返回一个帧到10,然而我们在第11帧,即使第11帧的数据是即将被写入的,第12帧的数据也将被写入不在那里。那有意义吗?对不起,我很难解释这一点! :) –

+0

@Sam你也可以做一个副本,如果你想,你没有显示足够的逻辑知道是否有必要。问题在于,两个指针都不是'const',所以你可以在这一点上做任何事情 - 唯一的限制是'currentData'和'discoveredData'的消费者。 –

+0

我明白了,是的,我认为你是对的 - 那将是最好的选择。谢谢! –

1

这是一个非常有趣的问题。我认为你在data race的问题是在适合并发的条件下实现的。

正如在单独的question中所讨论的那样,操纵想要的那个的一种可能方式是const将修改变量为mutable

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

除了关键字mutable之外,您应该考虑使用const_cast重新设置您的变量。

相关问题