管理:ヽ(゚∀。)ノうぇね

Programing Enlightened

ナビゲーション リンクのスキップ

プロパティ


 C++/CLI においてプロパティはいろいろと楽しいことが可能です。
 特に、インターフェイスやジェネリクス、メソッド・オーバーライド(メソッド上書き)と組み合わせて変わったことが楽しめます。

トリビアル・プロパティ(簡易プロパティ)


 public な変数を使うくらいなら、これを使いましょう。

public ref class TestClazz
{
public:
    TestClazz() {}
    property int Trivial;  // これがトリビアル・プロパティ
};

int main(stdcli::array<String^>^ args)
{
    TestClazz cls;
    cls.Trivial = 7;
    Console::WriteLine(cls.Trivial);
}

 こうするとコンパイラが自動的に変数のセッターとゲッター、そして、自動変数を用意してくれます。
 構造体とかで使うと便利になるのかな。


スコープのアクセサのアクセス指定


 managed C++ で可能だったアクセサ関数毎のアクセサ指定も次のようにできます。

public ref class SampleSlazz
{
private:
    _value;
public:
    SampleClazz() : _value(0)
    {
    }
    property int Value
    {
        int get() { return this->_value; }
    private:
        void set(int value)
        {
            this->_value = value;
        }
    }
    int _Value;
};

int main(stdcli::array<String^>^ args)
{
    SampleClazz sample;
    sample.Value = 7;    // コンパイル・エラー
    sample._Value = 10;  // プロパティ外にアクセサ指定子は影響しないので、publicメンバ
    Console::WriteLine("Value : {0}", sample.Value);
}

 この例では、セッターを private に指定しているので、外部からの Value プロパティへの値の代入はできません。

プロパティとインターフェイスとジェネリクス


 この面白い組み合わせでいろいろとできます。

public interface class IValue
{
    property int Value;
};

public interface class IA : IValue
{
};

public interface class IB : IValue
{
};

public ref class ClazzImpl : IA, IB
{
private:
    int _value_a_impl;
    int _value_b_inpl;

public:
    ClazzImpl() : _value_a_impl(0), _value_b_impl(0)
    {
    }

    virtual property int VA
    {
        int get() override = IA::Value::get
        {
            return this->_value_a_impl;
        }
        void set(int value) override = IA::Value::set
        {
            this->_value_a_impl = value;
        }
    }
    virtual property int VB
    {
        int get() override = IB::Value::get
        {
            return this->_value_b_impl;
        }
        void set(int value) override = IB::Value::set
        {
            this->_value_b_impl = value;
        }
    }
};

generic<typename T>
    where T : IValue
int AppendValue(T t, int incr)
{
    return t.Value + incr;
}

int main(stdcli::array<String^>^ args)
{
    ClazzImpl cls;
    Console::WriteLine("Value A = {0}", AppendValue( safe_cast<IA>(cls),  5 ) );
    Console::WriteLine("Value B = {0}", AppendValue( safe_cast<IB>(cls), 10 ) );
    Console::WriteLine("Result A = {0}", cls.VA );
    Console::WriteLine("Result B = {0}", cls.VB );
}

 こんな感じに、データと操作の振る舞いを必要な形態に対して処理することが可能です。



Topに戻る