自动 object 更改内存位置
Automatic object changes memory location
对于初学者,让我们考虑一下我目前正在从事的项目的以下摘要。这是 header:
class GUI {
public:
GUI& Initialize();
void DrawGUI(float width, float height);
private:
Model quad;
Shader sh;
Camera cam;
};
虽然这是 cpp 文件:
GUI& GUI::Initialize() {
quad.Initialize().LoadModel("Resources/quad.obj");
sh = Shader().Initiliaze();
sh.models.push_back(&quad);
return *this;
}
void GUI::DrawGUI(float width, float height) {
quad.SetScale(width, height, 0);
sh.RenderModels();
}
在直接解决问题之前,需要先解释一下。 Shader
object sh
将指向一定数量模型的指针存储在向量 vector<Model*> models
中。这些模型可以使用 RenderModels
方法渲染。
在初始化期间,GUI
通过 quad
的地址 &quad
将 quad
添加到 sh.models
。然后方法DrawGUI
可以用来缩放quad
并绘制到屏幕上。
问题:
在我的主函数中使用DrawGUI
时,缩放没有效果!
这是由于 "mysterious" 我希望有人能为我解开的行为。我已经知道问题的根源,但我无法掌握其背后的原因。
虽然SetScale
函数修改了quad
的维度,但这并不影响渲染,因为(我调试时验证过)&quad
和sh.models[0]
在[=时有不同的值23=] 被调用。特别是,quad
在初始化和绘制调用之间的某一时刻更改了它的地址,而我没有任何干预。一个小的改变解决了这个问题,缩放发生了:
void GUI::DrawGUI(float width, float height) {
sh.models[0].SetScale(width, height, 0);
sh.RenderModels();
}
但这并不能帮助我首先理解为什么会出现这个问题。事情变得更加不清楚,因为当使用自动存储声明 GUI
时出现问题,即 GUI gui;
,当我在堆上分配 GUI
时它不会出现。事实上 quad
不会更改地址,保持它与 sh.models[0]
相同并且一切正常。
为什么两种分配方式之间的行为不同?我缺少有关自动分配的内容吗?为什么 quad
更改其地址?
根据最新的评论,问题已经很清楚了。 OP 的代码中存在以下行:
GUI gui = GUI().Initialize();
Initialize
最重要的部分是:
GUI& GUI::Initialize() {
// ...
return *this;
}
因此,调用了 GUI 对象的复制构造函数。在没有任何用户提供的代码的情况下,使用默认的复制构造函数——并且由于 OP 还提到了指针,这些指针被复制为默认复制构造函数的一部分。但是没有人复制这些对象!事实上,没有人在新对象上调用 Initialize
。
给出的片段中的解决方案并不明确,但有几件事是显而易见的:
- 不要使用
Initialize
函数。使用构造函数,这就是它的用途。
- 仔细考虑复制您的对象。如有疑问,请删除复制构造函数和赋值运算符。
- 不要使用原始指针来管理对象,这就是智能指针的用途。在智能指针中,你的首选应该是
unique_ptr
.
对于初学者,让我们考虑一下我目前正在从事的项目的以下摘要。这是 header:
class GUI {
public:
GUI& Initialize();
void DrawGUI(float width, float height);
private:
Model quad;
Shader sh;
Camera cam;
};
虽然这是 cpp 文件:
GUI& GUI::Initialize() {
quad.Initialize().LoadModel("Resources/quad.obj");
sh = Shader().Initiliaze();
sh.models.push_back(&quad);
return *this;
}
void GUI::DrawGUI(float width, float height) {
quad.SetScale(width, height, 0);
sh.RenderModels();
}
在直接解决问题之前,需要先解释一下。 Shader
object sh
将指向一定数量模型的指针存储在向量 vector<Model*> models
中。这些模型可以使用 RenderModels
方法渲染。
在初始化期间,GUI
通过 quad
的地址 &quad
将 quad
添加到 sh.models
。然后方法DrawGUI
可以用来缩放quad
并绘制到屏幕上。
问题:
在我的主函数中使用DrawGUI
时,缩放没有效果!
这是由于 "mysterious" 我希望有人能为我解开的行为。我已经知道问题的根源,但我无法掌握其背后的原因。
虽然SetScale
函数修改了quad
的维度,但这并不影响渲染,因为(我调试时验证过)&quad
和sh.models[0]
在[=时有不同的值23=] 被调用。特别是,quad
在初始化和绘制调用之间的某一时刻更改了它的地址,而我没有任何干预。一个小的改变解决了这个问题,缩放发生了:
void GUI::DrawGUI(float width, float height) {
sh.models[0].SetScale(width, height, 0);
sh.RenderModels();
}
但这并不能帮助我首先理解为什么会出现这个问题。事情变得更加不清楚,因为当使用自动存储声明 GUI
时出现问题,即 GUI gui;
,当我在堆上分配 GUI
时它不会出现。事实上 quad
不会更改地址,保持它与 sh.models[0]
相同并且一切正常。
为什么两种分配方式之间的行为不同?我缺少有关自动分配的内容吗?为什么 quad
更改其地址?
根据最新的评论,问题已经很清楚了。 OP 的代码中存在以下行:
GUI gui = GUI().Initialize();
Initialize
最重要的部分是:
GUI& GUI::Initialize() {
// ...
return *this;
}
因此,调用了 GUI 对象的复制构造函数。在没有任何用户提供的代码的情况下,使用默认的复制构造函数——并且由于 OP 还提到了指针,这些指针被复制为默认复制构造函数的一部分。但是没有人复制这些对象!事实上,没有人在新对象上调用 Initialize
。
给出的片段中的解决方案并不明确,但有几件事是显而易见的:
- 不要使用
Initialize
函数。使用构造函数,这就是它的用途。 - 仔细考虑复制您的对象。如有疑问,请删除复制构造函数和赋值运算符。
- 不要使用原始指针来管理对象,这就是智能指针的用途。在智能指针中,你的首选应该是
unique_ptr
.