1

この質問にぴったりのタイトルが見つかりませんでした。

CheckBoxButtonおよびの 3 つのクラスがあり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);
}

ご覧のとおり、CheckBoxclass includesButton m_buttonButtonclass includes Background* m_pBg. コンストラクターでは、Background画像データをロードしてに保存しますがstd::vector、実際には問題ではありません。既にチェックされているため、機能していることがわかります。

CheckBoxオブジェクトを作成すると、その中のデータm_buttonが壊れています。デバッグモードで画像データの内容を確認しようとすると、空で、その背景のファイル名は"Error reading characters in string". デバッグモードでコードをステップバイステップで見たとき、データがコンストラクター内に適切にロードされていることがわかりましたが、どういうわけかオブジェクトが作成されたときに、データはすでに破損していました。

m_buttonクラスのフィールドをCheckBoxヒープ上に作成するように変更したとき(へのポインターButton、演算子を使用して作成されたオブジェクトnew)、すべてが正常に機能しているようです。データは正常にロードされており、このままです。

このような問題の原因は何ですか?

4

2 に答える 2

2

問題は、3 つのルールに従っていないことです。

クラスButtonはメモリ自体を管理するため、コピーを作成したり割り当てを行ったりすると、問題が発生する可能性があります。私はコードを掘り下げていないので、これがルートであるとは断言できませんが (それでも問題はあります)、そうであると確信しています。

リソースを管理するために raw ポインターの代わりにスマート ポインターを使用した場合、これはすべて回避できます。

于 2012-11-19T16:21:47.847 に答える
1

のコンストラクタのButton初期化リストでスタックに作成されたものは、フィールドCheckBoxにコピーされていm_buttonます:

m_button = Button();

default =operator が行っていることは、新しく作成された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同じオブジェクトを指す2 つの があります。Backgroundしかし、Buttonリストの初期化で作成された2番目のリストは、スコープから外れると破壊され、おそらく(Buttonクラスのデストラクタを見たことがないため)何が起こっているのか、デストラクタでBackgroundオブジェクトを破壊していますButton。そのため、デバッグ モードでコードをたどると、正しく created が表示されますBackgroundが、後でオブジェクトと共に破棄されButtonます。

于 2012-11-20T14:14:44.513 に答える