Gtk::manageによるdeleteの自動化

概要

Gtk::manageによるwidgetのdeleteの自動化について説明する。

widgetをnewで作成したときは通常のポインタと同様にdeleteでメモリを明示的に解放する必要が あるが、Gtk::manageによってdelete処理を自動化し、delete忘れによるメモリリークの危険を無くすことが出来る。 具体的にはnewしたwidgetをGtk::manageを使って親コンテナの管理下に置くことによって、 親コンテナが解放されたときに管理下にある子widgetも同時に削除されるようになる。 したがって特に理由が無い限りはwidgetをnewする際はGtk::manageを使用しておくのが安全である。

ソース

manage.cpp

#include <gtkmm.h>

#include <iostream>

class MyButton : public Gtk::Button
{
public:
    virtual ~MyButton(){
        std::cout << "~MyButton\n";
    }
};

class MainWin : public Gtk::Window
{

    MyButton* m_button;

public:
    MainWin(){
        m_button = Gtk::manage( new MyButton() );
        m_button->add_label( "manage" );

        add( *m_button );
        show_all_children();
    }

    virtual ~MainWin(){
        std::cout << "~MainWin\n";
    }
};

int main( int argc, char *argv[] )
{
    Gtk::Main kit( argc, argv );
    MainWin mainwin;
    Gtk::Main::run( mainwin );

    return 0;
}

コンパイル

必要なコンパイルオプションは pkg-config を使って取得する。

g++ manage.cpp -o manage `pkg-config gtkmm-2.4 --cflags --libs`

結果

上を実行してウィンドウを閉じた場合、
$ ./manage 
~MainWin
~MyButton
子widgetが削除されていることが分かる。一方 new の部分を
m_button = new MyButton();
と変更して実行すると
$ ./manage 
~MainWin
となり子widgetが削除されていないことが分かる。