初めてのC++/CLIその3
今回は型についてです。C#やっててC++を知らない場合、class/structで混乱するかもしれません。C++におけるclass/structは単にアクセス修飾子のデフォルトがprivate/publicの違いだけです。では値型、参照型は何で決まるのかというとref/valueキーワードに因ります。
#include "stdafx.h" using namespace System; // デリゲート delegate void Func(); // 親クラス(抽象クラス) ref class BaseClass abstract { int num; public: BaseClass() : num(0) {} // イベント event Func^ FuncHandler; void Say() { // イベントが設定されていたら呼び出す if (FuncHandler != nullptr) FuncHandler(); } // 仮想関数 virtual void Method1() {Console::WriteLine("BaseClass::Method1");} virtual void Method2() {Console::WriteLine("BaseClass::Method2");} // プロパティ property int Number { int get() { return num; } void set(int value) { num = value; } } }; // 派生クラス(継承禁止) ref class SubClass sealed : public BaseClass { public: // オーバーライド virtual void Method1() {Console::WriteLine("SubClass::Method1");} // 親クラスのMethod2を上書きしない(newキーワード) virtual void Method2() new {Console::WriteLine("SubClass::Method2");} }; // インタフェース interface class IInterface { void Method(); }; // 参照型のクラス ref class RefClass : IInterface { public: // インタフェースの実装はpublicで無ければならない void Method() {} }; // 参照型の構造体(クラスとはデフォルトのアクセス修飾子が違うだけ ref struct RefStruct : IInterface { // structのデフォルトはpublic // C#のclass/structとは違うので注意 void Method() {} }; // 値型のクラス value class ValueClass { public: void Method() {} }; // 値型の構造体 value struct ValueStruct { void Method() {} }; // 列挙型クラス enum class EnumClass { // publicつけなくても公開。class/structの差が無い? One,Two,Three }; // 列挙型構造体(フラグ属性あり) [Flags] enum struct EnumStruct { One,Two,Three }; void SayHello() { printf("Hello!\n"); } void SayGoodby() { printf("Goodby!\n"); } int _tmain() { // 派生クラスを生成して、ベースクラスに代入 BaseClass^ bc = gcnew SubClass; // 仮想関数呼び出し // 派生クラスのMethod1が呼ばれる bc->Method1(); // 親クラスのMethod2が呼ばれる(newがあるので親クラスのMethod2は隠されない) bc->Method2(); // ベースクラスのイベントに登録 bc->FuncHandler += gcnew Func(SayHello); bc->FuncHandler += gcnew Func(SayGoodby); // イベント呼び出し bc->Say(); // プロパティ bc->Number = 10; Console::WriteLine("Number = {0}", bc->Number); // 列挙型 Console::WriteLine(EnumClass::One); // 列挙型(フラグ属性があるのでORに対応) Console::WriteLine(EnumStruct::Two | EnumStruct::Three); Console::ReadLine(); } /* 結果 SubClass::Method1 BaseClass::Method2 Hello! Goodby! Number = 10 One Two, Three*/
マネージドコードだけだとC#とあんま変わらない感じですが、これにネイティブコードが混じってくると分かり難くなるんだろうなぁ・・・