« 2010年5月 | トップページ | 2010年7月 »

2010年6月

2010年6月20日 (日)

基底クラスのデストラクタにvirtualをつけない

また、横道にそれます。

普通、基底クラスのデストラクタにはvirtualをつけます。そうしないと、派生クラスのデストラクタが呼ばれないのです。

たとえば、以下のような場合(かなり強引な感じですが・・・)、

class kihon {
public:
    kihon();
    ~kihon();
};

class hasei : publib kihon {
public:
    hasei();
    virtual ~hasei();
};

kihon* obj = dynamic_cast<kihon*>(new hasei);
delete obj;

deleteしたときに、~kihon()は呼び出されますが、~hasei()は呼ばれません。なので、基本的に基底クラスのデストラクタにはvirtualをつけなくてはなりません。

しかし、デストラクタにvirtualをつけない方が好ましい場合があります。

それは、基底クラスを基底として扱わないときになります。

しかし、デストラクタにvirtualをつけないだけで、基底として扱えなくなるわけでもありません。これは、あくまでも、意思表示みたいなものになります。あと、コンストラクタ、デストラクタをprotectedにしておいた方がよいかと思われます。そもそも、基底として使わないので、deleteとかする必要がないでしょうから。

では、基底クラスを基底として扱わないとはどのような場合になるのでしょうか?

ちょうどいい例がboostライブラリにありました。noncopyableクラスというのを参照していただければ、 基底として扱わない場合の一例を知ることができると思います。

| | コメント (0) | トラックバック (0)

2010年6月13日 (日)

関数のなかに関数を入れる

ちょっと横道にそれますよ。

使う機会は余りありませんが、たまに欲しくなる関数内関数。ネットをさまよっていて、気になることを見つけました。

C言語では、定義することはできませんが、C++では、工夫次第で、実現できるそうです。その工夫とは、『関数内で構造体を宣言し、その構造体の中に静的メンバ関数を実装する』ということです。

なるほど、これならば、全然問題なさそうです。ということで、実際にコードにおこして試してみました。

#include <iostream>

using namespace std;

int main( int argc, char** argv ) {
    struct infunc {
        static int test( int a ) {
            return a;
        }
    };

    cout << infunc::test( 10 ) << endl;
    return 0;
}

何の実用性もないコードですが、普通にコンパイルを通って、実行できました。

関数の中に関数を置けたのはいいのですが、ちょっと見づらいですね。

あまり使う機会は無いと思いますが、関数を実装しているときに、関数内関数があればなぁと思い立ったときに使ってみるといいかもしれません。おそらく、そういうときには、関数外に関数定義するよりも、メリットがあるときだと思います。

| | コメント (0) | トラックバック (0)

« 2010年5月 | トップページ | 2010年7月 »