gtr*_*rak 8 c++ oop class operator-overloading operators
这是用C++编写的.
因此,我从头开始编写游戏引擎,以便从头开始学习乐趣和学习.我想实现的一个想法是让游戏对象状态(一个结构)是双缓冲的.例如,通过保证游戏对象中存储的一致状态(来自上次的数据),我可以让子系统更新新游戏对象数据,同时渲染线程从旧数据渲染.渲染旧并更新完成后,我可以交换缓冲区并再次执行.
问题是,在尝试尽可能隐藏实现细节的同时,将这个暴露给我的类是什么是一个很好的前瞻性和通用的OOP方式?想了解您的想法和注意事项.
我在想可以使用运算符重载,但是如何在缓冲区类中为模板化类的成员重载赋值?
例如,我认为这是我想要的一个例子:
doublebuffer<Vector3> data;
data.x=5; //would write to the member x within the new buffer
int a=data.x; //would read from the old buffer's x member
data.x+=1; //I guess this shouldn't be allowed
Run Code Online (Sandbox Code Playgroud)
如果可以,我可以选择启用或禁用双缓冲结构,而无需更改太多代码.
这就是我在考虑的事情:
template <class T>
class doublebuffer{
T T1;
T T2;
T * current=T1;
T * old=T2;
public:
doublebuffer();
~doublebuffer();
void swap();
operator=()?...
};
Run Code Online (Sandbox Code Playgroud)
并且游戏对象将是这样的:
struct MyObjectData{
int x;
float afloat;
}
class MyObject: public Node {
doublebuffer<MyObjectData> data;
functions...
}
Run Code Online (Sandbox Code Playgroud)
我现在所拥有的是返回旧缓冲区和新缓冲区指针的函数,我想任何使用它们的类都必须知道这一点.有没有更好的办法?
我最近通过"快照" 在引擎盖下使用Copy-On-Write的数据结构以一种通用的方式处理了类似的愿望.我喜欢这个策略的一个方面是,如果你需要它,你可以制作许多快照,或者只是一次一个地获得你的"双缓冲区".
没有出汗过多的实现细节,这里有一些伪代码:
snapshottable<Vector3> data;
data.writable().x = 5; // write to the member x
// take read-only snapshot
const snapshottable<Vector3>::snapshot snap (data.createSnapshot());
// since no writes have happened yet, snap and data point to the same object
int a = snap.x; //would read from the old buffer's x member, e.g. 5
data.writable().x += 1; //this non-const access triggers a copy
// data & snap are now pointing to different objects in memory
// data.readable().x == 6, while snap.x == 5
Run Code Online (Sandbox Code Playgroud)
在您的情况下,您将快照您的状态并将其传递给渲染.然后,您将允许您的更新对原始对象进行操作.使用const访问来读取它readable()
不会触发副本...访问时writable()
会触发副本.
我在Qt的QSharedDataPointer上使用了一些技巧来做到这一点.它们通过( - >)区分const和非const访问,这样从const对象读取不会触发写入机制上的副本.
如果我是你,我不会做任何"聪明"的操作员重载.将它用于完全不令人惊讶的东西,尽可能接近本机操作员所做的事情,而不是别的.
不清楚你的方案特别有助于多个写入线程 - 当几个线程读取旧状态并写入相同的新状态,覆盖任何先前的写入时,您如何知道哪个'获胜'?
但是如果它在你的应用程序中是一种有用的技术,那么我将拥有'GetOldState'和'GetNewState'方法,这些方法可以让它完全清楚发生了什么.