C++純虚関数と抽象クラス
10153 ワード
純粋な虚関数と定義
多くの場合、ベースクラスでは虚関数に意味のある実装を与えることができず、純粋な虚関数として説明される.純虚関数は関数体のない虚関数であり,その実現はこのベースクラスの派生クラスに残され,これが純虚関数の役割である.
純虚関数のフラグは、宣言後に特殊な構文=0があることです.
抽象クラス
純粋な虚関数を持つクラスを抽象クラスと呼ぶ.抽象クラスは特殊なクラスで、抽象と設計の目的のために構築され、継承階層の上位にあります.
要件:
少なくとも1つの純虚(pure virtual)
方法.
抽象クラスはオブジェクトを定義できません.実際には、クラスが抽象クラスであることを強調するために、クラスの構造関数を保護されたアクセス制御権限として説明できます.
クラスのコンストラクション関数がプライベートと宣言されている場合、クラスとクラスの派生クラスはオブジェクトを作成できません.コンストラクション関数が保護型として宣言されている場合、クラスはオブジェクトを作成できませんが、派生クラスはオブジェクトを作成できます.
抽象クラスには通常派生クラスがあります.
派生クラスのない抽象クラスは余計です
.
たとえば
抽象クラスはベースクラスとしてのみ使用でき、抽象クラスのオブジェクトは作成できませんが、抽象クラスのポインタと参照は抽象クラスから派生したクラスのオブジェクトを指すことができます.
抽象クラスから派生したクラスは、ベースクラスの純粋な虚関数を実装する必要があります.そうしないと、派生クラスはオブジェクトを作成できません.
上記の例では、派生クラスにベースクラスの純虚関数が定義されていない(派生クラスはベースクラスの純虚関数をリセットしない)と、派生クラス自体が抽象クラスとなり、インスタンス化できない.
抽象クラスフィーチャー:
1.複数の(≧1)純虚法を有することができる.
2.非純虚の方法があることができる.
3.虚でない方法がある.
4.データメンバーを持つことができる.
5.メンバーのアクセス制御(外部視認度)を定義できます.
その中の後4点はすべてのクラスの共通の特徴である.
抽象クラスの用途
1.
抽象ベースクラスは、ファミリークラスの共通インタフェースを説明するために使用されます.
(
shared interface
).
2.
抽象クラスは、あるソフトウェア設計のニーズを示すために使用できます.
多くの場合、ベースクラスでは虚関数に意味のある実装を与えることができず、純粋な虚関数として説明される.純虚関数は関数体のない虚関数であり,その実現はこのベースクラスの派生クラスに残され,これが純虚関数の役割である.
class A
{
private:
int a;
public:
virtual void Print( ) = 0 ; //
void fun( )
{
cout << "fun";
}
};
純虚関数のフラグは、宣言後に特殊な構文=0があることです.
抽象クラス
純粋な虚関数を持つクラスを抽象クラスと呼ぶ.抽象クラスは特殊なクラスで、抽象と設計の目的のために構築され、継承階層の上位にあります.
要件:
少なくとも1つの純虚(pure virtual)
方法.
抽象クラスはオブジェクトを定義できません.実際には、クラスが抽象クラスであることを強調するために、クラスの構造関数を保護されたアクセス制御権限として説明できます.
クラスのコンストラクション関数がプライベートと宣言されている場合、クラスとクラスの派生クラスはオブジェクトを作成できません.コンストラクション関数が保護型として宣言されている場合、クラスはオブジェクトを作成できませんが、派生クラスはオブジェクトを作成できます.
抽象クラスには通常派生クラスがあります.
派生クラスのない抽象クラスは余計です
.
たとえば
class B1
{
protected:
B1() {}
};
class B2
{
private:
B2() {}
};
class D1 : public B1
{
public:
D1() {}
};
class D2 : public B2
{
public:
D2() {} // error C2248: “B2::B2”: private ( “B2” )
};
int main()
{
B1 b1; // error C2248: “B1::B1”: protected ( “B1” )
B2 b2; // error C2248: “B2::B2”: private ( “B2” )
D1 d1; // OK
D2 d2; // error
return 0;
}
抽象クラスはベースクラスとしてのみ使用でき、抽象クラスのオブジェクトは作成できませんが、抽象クラスのポインタと参照は抽象クラスから派生したクラスのオブジェクトを指すことができます.
A a ; // ,A ,
A * pa ; // ok,
pa = new A ; // , A ,
抽象クラスから派生したクラスは、ベースクラスの純粋な虚関数を実装する必要があります.そうしないと、派生クラスはオブジェクトを作成できません.
class Base
{
public:
virtual void func( ) = 0;
};
class Derived : public Base { }
int main( )
{
Derived d; //error C2259: “Derived”:
return 0;
}
上記の例では、派生クラスにベースクラスの純虚関数が定義されていない(派生クラスはベースクラスの純虚関数をリセットしない)と、派生クラス自体が抽象クラスとなり、インスタンス化できない.
抽象クラスフィーチャー:
1.複数の(≧1)純虚法を有することができる.
2.非純虚の方法があることができる.
3.虚でない方法がある.
4.データメンバーを持つことができる.
5.メンバーのアクセス制御(外部視認度)を定義できます.
その中の後4点はすべてのクラスの共通の特徴である.
class ABC
{
public:
ABC( )
{
…
}
ABC(int x)
{
…
}
~ABC( )
{
…
}
virtual void open( ) = 0;
virtual void print()
{
…
}
int getCount( )
{
…
}
private:
int n;
}
抽象クラスの用途
1.
抽象ベースクラスは、ファミリークラスの共通インタフェースを説明するために使用されます.
(
shared interface
).
class BasicFile
{
public:
virtual int open( ) =0;
virtual int close( ) =0;
virtual int flush( ) = 0;
};
class InFile : public BasicFile
{
public:
virtual int open( )
{
…
};
virtual int close( )
{
…
};
virtual int flush( )
{
…
};
};
class OutFile : public BasicFile
{
public:
virtual int open( )
{
…
};
virtual int close( )
{
…
};
virtual int flush( )
{
…
};
};
2.
抽象クラスは、あるソフトウェア設計のニーズを示すために使用できます.
class IIntroSpect
{
public:
virtual void listFields ( ) =0;
virtual void listMethods( ) =0;
};
class MyClass : public IIntroSpect//
{
public:
void listFields ( )
{
…
};
void listMethods( )
{
…
};
// other members of MyClass
};