2014-10-02

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

5 comments:

Anonymous said...

RTTIの無いクラスというのはあまり意味を感じないですね。
そのようなCのクラス自体は今までもできましたし、ただのシンタックスシュガーですねぇ。
まぁ、規格がわで整理した方が利用者にもわかりやすくていいと思います。
Cに一番入ってほしいのは、オーバーライドとテンプレートなんですよね。
CはC++ではなくてJSを目指すべきです。
昔、
http://dway.web.fc2.com/pages/CLang/cpages/07_interface.htm
みたいなコードを書いたことがあります。
ただそれのシンタックスシュガーであるだけと、大事なことなので二回書いておきます。

Anonymous said...

オーバーロードとオーバーライドをよく間違えます。どっちがどっちでしたっけ??Orz

Anonymous said...

オーバロードは同名で引数違いを作る(過積載なイメージ?)で、オーバライドは継承したメソッドを覆いかぶせる(乗っかる?)と、私は覚えてます。
Cにオーバーロードとテンプレートがあるとかなりいいですね。
クラス(オブジェクト指向)はあれば便利なこともあるけど、なくてもいいと思ってます。

Anonymous said...

N298、N424とか、昔から提案自体はたまにあったようですね。オンラインドキュメント化されてないみたいですが。

今はなきC MAGAZINEの和訳コラムで、DinkumwareのP. J. Plauger氏が「否決された当時はがっかりした」みたいなこと書いてた気が。

Unknown said...

あなたはここからダウンロードすることができます任意のソフトウェアをダウンロードする場合。 ダウンロードするにはこちらをクリック