oop — неверные данные в объектах, созданных в стеке

Я не мог найти лучшего названия для этого вопроса.

У меня есть три класса: CheckBox, Button а также Background,

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);
}

Итак, как вы можете видеть, CheckBox класс включает в себя Button m_button а также Button класс включает в себя Background* m_pBg, В Background Конструктор Я загружаю данные изображения и сохраняю их в std::vector, это не имеет значения — я знаю, что это работает, потому что это уже проверено.

Когда я создаю CheckBox объект, данные внутри него m_button поврежден Когда я пытаюсь проверить, что находится внутри данных изображения в режиме отладки, я получаю информацию, что она пуста, и имя файла этого фона "Error reading characters in string", Хотя, когда я увидел следующий шаг за шагом код в режиме отладки, я увидел, что данные были правильно загружены в конструктор, но каким-то образом, когда объект был создан, данные уже были повреждены.

Когда я изменился m_button поле в CheckBox класс, который будет создан в куче (указатель на Buttonобъект, созданный с помощью new оператор) все вроде работает просто отлично. Данные загружаются правильно и остаются такими.

Может ли кто-нибудь объяснить мне, что может быть причиной такой проблемы?

1

Решение

Ваш Button который создается в стеке в списке инициализации CheckBoxконструктор копируется в m_button поле:

m_button = Button();

Оператор default = выполняет копирование каждого поля внутри нового созданного Button Возражать m_button:

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;

Оба указателя теперь указывают на один и тот же объект! И то же самое случилось с вашим Background*, У вас есть два Buttonс, которые указывают на то же самое Background объект где-то в памяти. Но твой второй Button созданный в списке инициализации уничтожается, поскольку он выходит из области видимости и что, вероятно, (потому что я не видел деструктора вашего Button класс) происходит, вы уничтожаете Background объект в вашем Button деструктор. Вот почему, когда вы следите за кодом в режиме отладки, вы видите правильно созданный Background, но позже он разрушается с Button объект.

1

Другие решения

Проблема в том, что вы не подчиняетесь правило трех.

Класс Button управляет самой памятью, поэтому, когда вы создаете копии или делаете назначения, вы, скорее всего, столкнетесь с проблемами. Я не копался в коде, поэтому не могу с уверенностью сказать, что это корень (тем не менее, это проблема), но я уверен, что это так.

Этого можно избежать, если вы используете умные указатели вместо необработанных указателей для управления ресурсами.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector