本の虫

著者:江添亮
ブログ: http://cpplover.blogspot.jp/
メール: boostcpp@gmail.com
Twitter: https://twitter.com/EzoeRyou
GitHub: https://github.com/EzoeRyou

アマゾンの江添のほしい物リストを著者に送るとブログ記事のネタになる

筆者にブログのネタになる品物を直接送りたい場合、住所をメールで質問してください。

N1875: C言語にクラスを追加する提案

ask.fmで、面白い質問が来た。なんと、C言語にクラスを追加する提案論文が、先月末に公開されているというのだ。

N1876: Adding classes to C

C言語の標準規格は追っていないのだが、なかなか興味深い。

この提案は、C言語にC++風のクラス機能を追加する提案だ。ただし、C++のクラスをそのまま持ってくるのではなく、だいぶ保守的な採用の仕方をしている。

この論文で提案されているクラス機能は、C++の文法によく似ている。クラスstructかclassキーワードで宣言する。アクセス指定子もあり、structはデフォルトでpublic、classはデフォルトでprivateなのも、C++と同じだ。

派生はあるが、多重派生は認められていない。

virtual関数やRTTIはない。

また、C++にある、自動的に呼ばれるコンストラクター、デストラクターは存在しない。

かわりに、イニシャライザー、デリーターというものがある。これは、特定の名前を特別視する文法になるようだ。あるクラスClassNameがあるとして、イニシャライザーとデリーターは、それぞれ、initClassName, deleteClassNameと記述する。文法は、戻り値の型がない以外はメソッドと同じようだ。

struct Data
{
    int * ptr ;

    // 無引数イニシャライザー
    initData() { }

    // イニシャライザーはオーバーロードできる
    initData( int value )
    {   // thisキーワードはオブジェクトへのポインター
        ptr = (int *) malloc( sizeof(int) ) ;
        *ptr = value ;
    }

    // デリーター
    deleteData()
    {
        free( ptr ) ;
    }

    // デリーターもオーバーロードできる
    deleteData( int some_flags )
    {
        free ( ptr ) ;
    }

} ;

int main()
{
    Data d.initData( 123 ) ;

    // 明示的なデリーター呼び出しが必要
    // C++のように自動的に呼ばれることはない。
    d.deleteData() ;
}

派生は、単一派生のみ存在するが、イニシャライザーやデリーターが自動的に呼ばれることはない。呼ぶ必要があれば、明示的に呼ばなければならない。

struct CustomData : public Data
{
    
    initCustomData ()
    {
        // 基本クラスのイニシャライザーの呼び出しが必要であれば
        // 明示的に呼びださねばならない。
        initData( 123 ) ;
    }

    deleteCustomData()
    {
        // デリーターも同様
        deleteData( ) ;
    }
} ;

論文では、明示的なイニシャライザーとデリーターの呼び出しを、CUYOM (Clean Up Your Own Mess)、「テメーのケツはテメーで拭け」としている。いかにもC言語らしいシキタリであると言える。

C++と同じアクセス指定子が存在する。その意味もC++とまったく同じだ。


struct X
{
public :
    int x ;
protected :
    int y ;
private :
    int z ;
} ;

メンバー関数(論文ではメソッドという用語を使っている)の宣言と呼び出しは、C++と同じ文法で行う。

struct X
{
    void method() { }
} ;

void f( X x, X * p )
{
    x.method() ;
    p->method() ;
}

また、C++と同じように、thisポインターがある。

struct X
{
    int m ;
    void f()
    {
        // thisキーワードはX *型のポインター
        this->m = 0 ;
    }
} ;

論文では、C風の初期化もできるとしているが、以下のようなコードになっている。

struct Data
{
    int a ;
    int b ;
} ;

Data d = ( 1, 2 ) ;

また、途中のデータメンバーの初期化をスキップする文法も是非標準規格に入れたいと論文は書いている。


struct Data
{
    int a ;
    int b ;
    int c ;
} ;

// d.bの初期化は行われない
Data d = ( 1, , 3 ) ;

興味深いものの、C++畑の人間からすると、いろいろともやもやする部分が多い。

ドワンゴ広告

この記事はドワンゴ勤務中に書かれた。

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0