抽象ベースクラスはインスタンス化できませんか?どうやって破るんだ?

4464 ワード

C++を学んだことがある人はすべてC++の中の抽象的な基類を知っているはずで、私たちが1つの基類がインスタンス化されない必要がある時、抽象的な基類は登場する必要があります.
通常は、少なくとも1つの純粋な虚関数を定義することによって実現されます.たとえば、抽象ベースクラスの例を次に示します.
class Abstract

{

public:

    Abstract(int data = 0){

        m_data = data;

    };

    virtual int getdata() = 0;

private:

    int m_data;

};

Abstractの例を定義したいのですが
int _tmain(int argc, _TCHAR* argv[])

{

    Abstract a;

    return 0;

}

コンパイル中にエラーが発生し、ヒントが表示されます.
error C 2259:Abstract:抽象クラスをインスタンス化できません1>次のメンバーのため:1>int Abstract::getdata(void):抽象的です
 
これが抽象ベースクラスの役割であり,継承できるが直接インスタンス化できない.
抽象ベースクラスをインスタンス化したい場合は、どうすればいいですか?実はまだ方法がある.
たとえば、抽象クラスの配列を次のように定義して初期化します.
int _tmain(int argc, _TCHAR* argv[])

{

    Abstract arr[1] = {3};

    return 0;

}

コンパイルを行って、鉄棒の、木はどんな問題があります!
抽象クラスで純虚関数を呼び出したいですか?何の問題もありませんが、実際には、C++は純粋な虚関数を定義することを許可しています.これにより、コードを次のように変更することができます.
class Abstract

{

public:

    Abstract(int data = 0){

        m_data = data;

    };

    virtual int getdata() = 0;

private:

    int m_data;

};



int Abstract::getdata(){

    return m_data;

}

int _tmain(int argc, _TCHAR* argv[])

{

    Abstract arr[1] = {3};



    cout<<arr[0].getdata()<<endl;

    

    return 0;

}

実行すると、結果は3!これはまさに私たちが望んでいるものです!
 
しかし、上記の方法は成功するが、定義された抽象クラスで抽象クラスを直接初期化するにはエラーが発生する.
    Abstract arr[1] = {3};

    Abstract a = arr[0];

コンパイル中にエラーが発生します.
 
ポインタまたはリファレンスでオブジェクトを指すとコンパイルに成功します
    Abstract arr[1] = {3};

    Abstract* a = &arr[0];

ただし、ポインタまたはリファレンスで純粋な虚関数を呼び出すと、実行中にエラーが発生します.
    cout<<a->getdata()<<endl;

 
ポインタまたはリファレンスで非純粋な虚関数を呼び出すと、正常に実行できます.
 
注:本実験はVS 2008専門版で行い、環境によって結果が異なる場合があります.