クラス色々

なんか間違って消してしまったので貼り直し。(^^;

C#と同じくらい簡単に書けるよーになった云々とか書いた記憶が。イベントをいちいちnullptrチェックしなくていいのは良いですね。

#include "stdafx.h"

using namespace System;

// デリゲート
delegate void MyDelegate();

ref class Foo {
    // literalはC#のconst
    literal double PI = 3.141592;
    // initonlyはC#のreadonly
    initonly static int bar;
    int baz;
    array<int>^ qux;
    array<int, 2>^ quux;
    // スタティックコンストラク
    static Foo () {
        bar = 0;
    }
public:
    // コンストラク
    Foo() {
        baz = 0;
        qux = gcnew array<int>(10);
        quux = gcnew array<int, 2>(10, 10);
    }
    Foo(int n) : baz(n) {
        qux = gcnew array<int>(10);
        quux = gcnew array<int, 2>(10, 10);
    }

    // Disposeメソッド
    ~Foo() {
        Console::WriteLine("Dispose");
    }

    // Finalizeメソッド
    !Foo() {
        Console::WriteLine("Finalize");
    }

    // プロパティ
    property int Baz {
        int get() {
            return baz;
        }
        void set(int value) {
            baz = value; 
        }
    }

    // インデクサ
    property int default [int] {
        int get(int index) {
            return qux[index];
        }
        void set(int index, int value) {
            qux[index] = value; 
        }
    }
    // インデクサ(引数2つ)
    property int default[int, int] {
        int get(int x, int y) {
            return quux[x, y];
        }
        void set(int x, int y, int value) {
            quux[x, y] = value; 
        }
    }

    // 仮想関数
    virtual void f() {}
    virtual void g() {}
    virtual void h() {}

    // イベント^(トラッキングハンドル)が必要なことに注意)
    event MyDelegate^ Handler;

    void OnHandler() {
        // C#と違い、if (Handler != nullptr)のようにチェックする必要がない
        Handler();
    }
};

// C++/CLIのデフォルトはパブリック継承
ref class Bar : Foo {
public:
    Bar() {}
    // ベースクラスの非デフォルトコンストラクタを呼ぶ
    Bar(int n) : Foo(n) {
    }
    // オーバーライド
    virtual void f() override { Console::WriteLine("Bar::f()"); }
    // 上書き
    virtual void g() new {}
    // 継承禁止
    virtual void h() override sealed {}
};

int main(array<System::String ^> ^args)
{
    Foo^ foo = gcnew Bar();
    foo[0] = 1;
    foo[0,0] = 2;
    // 空のイベントを呼んでみる
    foo->OnHandler();
    // イベントの追加
    // C#2.0と違ってdelegate経由でなければ渡せない
    foo->Handler += gcnew MyDelegate(foo, &Foo::f);
    foo->OnHandler();

    delete foo;

    return 0;
}