3 6月 2016
3 6月 2016
class CAnimal { public: CAnimal(); // 構造体 virtual void Sound() = 0; // 純粋仮想関数 private: double m_legs_count; // 足数 };ここでのSound()関数は、純粋仮想関数PURE(=0)の指定子で宣言されている為、純粋仮想となります。
class CAnimal { public: virtual void Sound()=NULL; // PUREメソッドは派生クラスで―バーライドする必要があり、CAnimalクラス自体は抽象クラスになり、作成されません }; //--- 抽象クラスからの子 class CCat : public CAnimal { public: virtual void Sound() { Print("Myau"); } // PUREはオーバーライドされ、CCatクラスは抽象クラスで、作成できます }; //--- 誤用例 new CAnimal; // 'CAnimal'エラーーコンパイラはエラー"cannot instantiate abstract class"を出します CAnimal some_animal; // 'CAnimal'エラー - コンパイラはエラー"cannot instantiate abstract class"を出します //--- 正しい使用例 new CCat; // エラーなし - CCatは抽象暮らしではない CCat cat; // エラーなし - CCatは抽象クラスではない抽象クラスの使用の制限
//+------------------------------------------------------------------+ //| 抽象基底クラス | //+------------------------------------------------------------------+ class CAnimal { public: //--- 純粋仮想関数 virtual void Sound(void)=NULL; //--- 関数 void CallSound(void) { Sound(); } //--- コンストラクタ CAnimal() { //--- 仮想メソッドの明示的呼び出し Sound(); //--- 暗黙的呼び出し(第三の関数を介して) CallSound(); //--- 仮想性や子孫における関数呼び出しの再定義に関わらず //--- コンストラクタまたはデストラクタでは常に自分の関数が呼び出されます //--- もし呼び出される関数が純粋仮想の場合 //--- 呼び出しは重大な実行エラー"pure virtual function call"をもたらします } };しかしながら、抽象クラスのコンストラクタとデストラクタは、他のメンバー関数を呼び出すことができます。
typedef int (*TFunc)(int,int);これで、TFuncがタイプとなり、変数の関数ポインターを宣言することができます。
TFunc func_ptr;func_ptr変数に、以後の呼び出しの為に、関数へのポインタを保存することができます。
int sub(int x,int y) { return(x-y); } int add(int x,int y) { return(x+y); } int neg(int x) { return(~x); } func_ptr=sub; Print(func_ptr(10,5)); func_ptr=add; Print(func_ptr(10,5)); func_ptr=neg; // エラー: negはint 型(int,int)を持っていません Print(func_ptr(10)); // エラー: 二つのパラメータがある必要があります関数のポインターを保存し、パラメータとして引き渡すことができます。クラスの非静的メソッドにポインターを取得することはできません。
クラッシュログで報告された不具合を修正しました。