C++ 在堆栈C+;上创建的对象中的数据无效+;
对于这个问题,我真的找不到更好的标题了 我有三个类:C++ 在堆栈C+;上创建的对象中的数据无效+;,c++,oop,pointers,stack,heap,C++,Oop,Pointers,Stack,Heap,对于这个问题,我真的找不到更好的标题了 我有三个类:复选框,按钮和背景 class CheckBox : public Component { private: Button m_button; public: CheckBox(const Point &pos, int width, int height, std::string text); CheckBox(); }; CheckBox::CheckBox(const Point &pos, in
复选框
,按钮
和背景
class CheckBox : public Component
{
private:
Button m_button;
public:
CheckBox(const Point &pos, int width, int height, std::string text);
CheckBox();
};
CheckBox::CheckBox(const Point &pos, int width, int height, string text) :
Component(pos, width, height),
m_button(Button(Point(width-height,0), new Background("button_bg_sample.png", true), new Background("button_bg_onclick_sample.png", true), height, height, 10, "")),
{
}
class Button : public Component
{
private:
std::string m_text;
Background* m_pBackground;
Background* m_pBackgroundOnClick;
int m_fontSize;
public:
Button(const Point& pos, Background* pBg, Background* pBgOnClick, int width, int height, int fontSize, std::string title);
~Button();
};
Button::Button(const Point& pos, Background* pBg, Background* pBgOnClick, int width, int height, int fontSize, string title) :
Component(pos, width, height),
m_pBackground(pBg),
m_pBackgroundOnClick(pBgOnClick),
m_fontSize(fontSize),
m_text(title)
{
}
class Background
{
private:
std::string m_pFileName;
bool m_bTiling;
std::vector<unsigned char> m_pImageData;
unsigned int m_width;
unsigned int m_height;
GLuint m_texture;
bool load(const std::string& pFileName);
public:
Background(const std::string& pFileName, bool bTiling);
~Background();
bool draw(const Point &pos, unsigned int width, unsigned int height);
bool draw(const Point &pos);
};
Background::Background(const string& pFileName, bool bTiling) :
m_bTiling(bTiling),
m_pFileName(pFileName)
{
load(pFileName);
}
class复选框:公共组件
{
私人:
按钮m_按钮;
公众:
复选框(常量点和位置、整数宽度、整数高度、标准::字符串文本);
复选框();
};
复选框::复选框(常量点和位置、整数宽度、整数高度、字符串文本):
组件(位置、宽度、高度),
m_按钮(按钮(点(宽-高,0)、新背景(“按钮”bg_sample.png,true)、新背景(“按钮”bg_onclick_sample.png,true)、高度、高度,10“),
{
}
类按钮:公共组件
{
私人:
std::字符串m_文本;
背景*m_p背景;
背景*m_pBackgroundOnClick;
int m_fontSize;
公众:
按钮(常量点和位置、背景*pBg、背景*pBg单击、整数宽度、整数高度、整数字体大小、标准::字符串标题);
~Button();
};
按钮::按钮(常量点和位置、背景*pBg、背景*pBg单击、整数宽度、整数高度、整数字体大小、字符串标题):
组件(位置、宽度、高度),
m_pBackground(pBg),
m_pBackgroundOnClick(pBgOnClick),
m_fontSize(fontSize),
m_文本(标题)
{
}
阶级背景
{
私人:
std::字符串m_pFileName;
布尔穆比林;
std::向量m_pImageData;
无符号整数m_宽度;
无符号整数m_高度;
胶状m_结构;
bool加载(const std::string和pFileName);
公众:
背景(const std::string和pFileName,bool bTiling);
~Background();
布尔图(常数点和位置、无符号整数宽度、无符号整数高度);
布尔图(常数点和位置);
};
背景::背景(常量字符串和pFileName,bool bTilling):
m_bTiling(bTiling),
m_pFileName(pFileName)
{
加载(pFileName);
}
如您所见,复选框
类包括按钮m_按钮
和按钮
类包括背景*m_pBg
。在Background
构造函数中,我加载图像数据并将其存储在std::vector
中,这并不重要-我知道它正在工作,因为它已经被检查过了
当我创建复选框
对象时,它的m_按钮
中的数据已损坏。当我试图在调试模式下检查图像数据内部的内容时,我得到的信息是图像数据是空的,背景文件名是“读取字符串中的字符时出错”
。虽然当我看到在调试模式下一步一步地执行代码时,我已经看到数据被正确地加载到构造函数中,但是在创建对象时,数据已经损坏了
当我更改要在堆上创建的CheckBox
类中的m_按钮
字段时(指向按钮
,使用新建
操作符创建的对象),一切似乎都正常工作。数据正在正确加载并保持如下状态
有谁能解释一下造成这种问题的原因吗?问题是你没有服从 class
按钮
管理内存本身,因此当您创建副本或进行分配时,您可能会遇到麻烦。我没有深入研究代码,所以不能肯定这是根源(尽管这是一个问题),但我非常肯定它是
如果您使用智能指针而不是原始指针来管理资源,这一切都可以避免。您的
按钮
将被复制到复选框的构造函数的初始化列表中的堆栈上
m_button = Button();
default=运算符正在做的是将新创建的按钮
对象中的每个字段复制到m_按钮
:
m_button.height = b.height // Let's assume, that 'b' is the name of this new Button
m_button.width = b.width
m_button.name = b.name
...
现在,如果您有一个指向某个对象的指针p1
,另一个指针p2
,并将p1
分配给p2
,会发生什么情况
int* p1 = new int(5);
int* p2 = p1;
两个指针现在都指向同一个对象!同样的事情也发生在你的背景上*
。您有两个按钮
s,它们指向内存中某个相同的背景
对象。但是您在初始化列表中创建的第二个按钮
正在被销毁,因为它超出了范围,并且很可能(因为我没有看到您的按钮
类的析构函数)正在发生什么,您正在销毁按钮
析构函数中的背景
对象。这就是为什么在调试模式下跟踪代码时,您会看到正确创建的背景
,但随后它会被按钮
对象销毁。您甚至没有提供所有代码,例如,~Button()破坏背景会怎么样?