こんにちは、高木です。
前回はTkのウィジェットを扱うための最小限のラッパークラスを作ってみました。今回はそこで作ったwidgetクラスを派生させて、ラベルウィジェットを扱うためのlabelクラスを作ってみましょう。
その前に、widgetクラスにいくつかのメンバー関数を追加しておくことにします。追加するメンバー関数は以下の通りです。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public: virtual ~widget() noexcept = default; tcl::obj path() const { return this->path_; } tcl::interpreter interpreter() const { return this->interp_; } tcl::obj type() const { return do_type(); } widget(const widget&) = default; widget(widget&&) = default; widget& operator=(const widget&) = default; widget& operator=(widget&&) = default; private: virtual tcl::obj do_type() const { return nullptr; } |
最初は仮想デストラクターです。これから派生クラスを作っていくので仮想デストラクターは必須ですね。また、widgetクラスのpath_とinterp_の2つのデーターメンバーはprivateなので、外部からも参照できるように取得用のメンバー関数を追加しておきます。この2つはpublicにしても問題ないでしょう。
ウィジェットの種類を返すtypeメンバー関数も用意してみました。念のためNVIにしたので、仮想関数であるprivateなdo_typeメンバー関数を呼び出す形にしています。
あとはコピーコンストラクター、ムーブコンストラクター、コピー代入演算子、ムーブ代入演算子を念のため明示的に定義しておきます。widgetクラスは実質的にウィジェットの名前しか管理しませんので、普通にコピーやムーブを行って問題ないと思います。
これを踏まえた上でlabelクラスを作っていきます。コードは次のようになります。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
namespace tk { class label : public widget { static constexpr char8_t type[] = u8"label"; public: label(const widget& parent, const tcl::obj& name, std::initializer_list<tcl::obj> options) : widget(type, parent, name, options) { } ~label() noexcept = default; label(const label&) = default; label(label&&) = default; label& operator=(const label&) = default; label& operator=(label&&) = default; private: virtual tcl::obj do_type() const { return type; } }; } |
デストラクター、コピーコンストラクター、ムーブコンストラクター、コピー代入演算子、ムーブ代入演算子はdefaultです。省略してもかまいませんが、念のため明示的に書いておくことにします。
重要なのはコンストラクターとdo_typeメンバー関数だけです。
まず、コンストラクターですが、ほとんどwidgetクラスのコンストラクターと同じです。ただし、typeはu8″label”に決まっていますので、指定しなくてもいいようにしています。次にdo_typeメンバー関数ですが、これはu8″label”を返すだけにしています。
今回はlabelクラスを作りましたが、typeだけを入れ替えて上げればほぼどんなウィジェットのラッパークラスでも作れそうですね。こういうときコードを自動生成した方がよさそうです。次回はPHPを使って複数のウィジェットクラスを自動生成してみることにしましょう。