あるクラスで確保した領域を別のクラスで開放するには? – プログラミング – Home

あるクラスで確保した領域を別のクラスで...
 
通知
すべてクリア

あるクラスで確保した領域を別のクラスで開放するには?


なおじー
 なおじー
(@なおじー)
ゲスト
結合: 20年前
投稿: 5
Topic starter  

はじめまして。
現在、あるクラスのモジュール内で別のクラス内で確保された領域を開放させる処理を
入れようと思っているのですが上手くいかず困っています。
内容は以下の通りです。
●ヘッダー定義内容
class A
{
public:
UCHAR* m_pB; // 取得領域へのポインタ
void C(void); // 領域を確保する処理があるモジュール
};
●void C(void)のモジュール内
*m_pB = new UCHAR[・・・]; // 領域確保
●開放処理を行いたいクラスのモジュール
void CSubDlg::OnClose()
{
//>>> ?
}
このような場合、OnClose()内でC(void)で確保した領域を開放するには?の部分にど
のように記述すればよいのでしょうか?よろしくお願いします。


引用解決済
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

void CSubDlg::OnClose() {
...
delete 開放したい領域を持ったオブジェクト.m_pB;
}


返信引用
なおじー
 なおじー
(@なおじー)
ゲスト
結合: 20年前
投稿: 5
Topic starter  

επιστημηさん。ありがとうございます。

”開放したい領域を持ったオブジェクト”とあるのですが、具体的にどのように定義す
ればよいのでしょうか?
よろしくお願いします。


返信引用
Takahashi
 Takahashi
(@Takahashi)
ゲスト
結合: 21年前
投稿: 45
 

メモリ確保のメンバ関数があるので解放するメンバ関数を作った方がいいのでは?
例えばこんなメンバ関数

void A::Delete()
{
if(m_pB != NULL){
delete m_pB;
m_pB = NULL;
}
}

void CSubDlg::OnClose()
{
開放したい領域を持ったオブジェクト.Delete();
}

この方が私的には好みです。
# m_pB は private にしてカプセル化した方がいいと思います。

あと、class A が CSubDlg のメンバならば class A のデストラクタで delete すれば
ダイアログの終了で勝手に delete してくれます。

# 開放したい領域を持ったオブジェクト ってのはこれでわかりますよね?


返信引用
NowNow
 NowNow
(@NowNow)
ゲスト
結合: 20年前
投稿: 27
 

AクラスをCSubDlgのメンバー変数として持っているなら...

//クラス定義
class A
{
public:
UCHAR* m_pB; // 取得領域へのポインタ
void C(void); // 領域を確保する処理があるモジュール
};

//SubDlgクラス
class CSubDlg
{
...
A m_A;
void OnClose():
...
};

void CSubDlg::OnClose()
{
...
delete m_A.m_pB;
}

こんな感じでいいのでは?
ただし、m_A.m_pBの指すポインタにちゃんとメモリー確保されているかどうかのチェック
機構を入れないと、変なポインタをdeleteする結果になるかもしれません。


返信引用
NowNow
 NowNow
(@NowNow)
ゲスト
結合: 20年前
投稿: 27
 

> void OnClose():

「:」 -> 「;」のミスです。すみません。
void OnClose();


返信引用
なおじー
 なおじー
(@なおじー)
ゲスト
結合: 20年前
投稿: 5
Topic starter  

Takahashi さん。ありがとうございます。

Takahashi さんのサンプルソースだとイメージ的にはCSubDlg::OnClose()で開放処理を
入れるのではなく、CSubDlg::OnClose()でクラスAで定義したDelete()モジュールを呼び
出すということですよね?
参考になりました。早速やってみたいと思います。また結果報告します。


返信引用
なおじー
 なおじー
(@なおじー)
ゲスト
結合: 20年前
投稿: 5
Topic starter  

NowNow さんありがとうございます。

ちなみにclass A は CSubDlg のメンバになっていますので早速やってみます。


返信引用
Takahashi
 Takahashi
(@Takahashi)
ゲスト
結合: 21年前
投稿: 45
 

より完璧にしたいのならば私はこう書きます

class A
{
UCHAR* m_pB; // 取得領域へのポインタ

public:
A() : m_pB() {}
~A() { Delete(); }

void C(void); // 領域を確保する処理があるモジュール
void Delete(); // さっきの解放する関数
};

これでリークする可能性はかなり減りますが、オブジェクトのコピーを考慮しなければな
りません。
例えばこんなコピーコンストラクタが必要です

A(const A& a)
{
if(a.m_pB != NULL){
// 新しい領域を確保して、a.m_pB をコピーする
}
}

コピーする必要がないのならばコピーコンストラクタを殺さないと(呼び出せなくする)メ
モリリークする可能性があります。
# 理由はわかりますよね?
結構めんどっちいので、UCHAR が単に文字列とかであれば CString とか std::string 等
を使用するか、コンテナ等利用できないか検討した方が楽です。


返信引用
なおじー
 なおじー
(@なおじー)
ゲスト
結合: 20年前
投稿: 5
Topic starter  

επιστημηさん 、Takahashi さん、NowNow さんありがとうございました。
無事領域開放することができました。

後、聞いておきたいことがあるのですが、VC++でデバッグ終了時、メモリリークが
あるとその内容がアウトプットに表示されるのですが、ここは該当データがちゃんと全
て表示されているのでしょうか?よろしくお願いします。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました