第19章 動的オブジェクト

 今回は、オブジェクトを動的に確保してみます。コンストラクタやデストラクタはどうなるのでしょうか?


 では、要点を先ず。


 では、いってみましょう。


 オブジェクトを動的に確保したいときというのもあります。そこで、CBinaryFile を new で確保してみましょう。

CBinaryFile* pbin;
pbin = new CBinaryFile;

と、new の文法からいってこれで間違いはないはずです(第1部第71章参照)。

 このとき、コンストラクタとかは呼ばれるのでしょうか? 呼ばれないと困りますよね。ということで、確かめてみましょう。ついでに、delete するときにデストラクタが呼ばれるかも確かめます。

プログラム1
// CBinFile.h
class CBinaryFile : public CFile
{
public:
    ~CBinaryFile();  // デストラクタ
};
プログラム2
// CBinFile.cpp
// デフォルトコンストラクタ
CBinaryFile::CBinaryFile()
{
    cout << "CBinaryFile::CBinaryFile 1" << endl;
}

// 構築と同時にファイルを開く
CBinaryFile::CBinaryFile(const char* pszPath, const char* pszFlags)
{
    cout << "CBinaryFile::CBinaryFile 2" << endl;
    Open(pszPath, pszFlags);
}

// コピーコンストラクタ
CBinaryFile::CBinaryFile(const CBinaryFile& rother) : CFile(rother)
{
    cout << "CBinaryFile::CBinaryFile 3" << endl;
}

// デストラクタ
CBinaryFile::~CBinaryFile()
{
    cout << "CBinaryFile::~CBinaryFile" << endl;
}
プログラム3
// TestFile.cpp
#include <iostream.h>
#include "BinFile.h"

void Viss(int num)
{
    cout << "Viss : " << num << endl;
}

int main()
{
    CBinaryFile* pbin;

    Viss(1);
    pbin = new CBinaryFile;
    if(pbin == NULL)
        return 0;

    Viss(2);
    delete pbin;

    Viss(3);

    return 0;
}
実行結果
Viss : 1
CBinaryFile::CBinaryFile 1
Viss : 2
CBinaryFile::~CBinaryFile
Viss : 3

 やはり呼ばれていますね。

 ということで、オブジェクトを動的に確保するときは、new のときにコンストラクタが、delete の時にコンストラクタが呼ばれます


 では、引数付きのコンストラクタは呼べるのでしょうか?

 指定できそうなところと言えば、new の CBinaryFile の後ろくらいですね。まぁ、とりあえずやってみましょう。

プログラム
// TestFile.cpp
#include <iostream.h>
#include "BinFile.h"

void Viss(int num)
{
    cout << "Viss : " << num << endl;
}

int main()
{
    CBinaryFile* pbin;

    Viss(1);
    pbin = new CBinaryFile("Test.txt", "r");
    if(pbin == NULL)
        return 0;

    Viss(2);
    delete pbin;

    Viss(3);

    return 0;
}
実行結果
Viss : 1
CBinaryFile::CBinaryFile 2
Viss : 2
CBinaryFile::~CBinaryFile
Viss : 3

 うまくいきました。

 このように、引数付きのコンストラクタを呼ぶときは、new に指定した型の後に実引数リストをくっつけます。特に問題はありませんね。


 では、配列で確保してみましょう。確か、配列でオブジェクトを作成するときはデフォルトコンストラクタしか呼べませんでした。ここでも同じなのでしょうか?

 まぁ、とりあえずやってみましょう。

プログラム
// TestFile.cpp
#include <iostream.h>
#include "BinFile.h"

void Viss(int num)
{
    cout << "Viss : " << num << endl;
}

int main()
{
    CBinaryFile* pbin;
    CBinaryFile   bin;

    Viss(1);
    pbin = new CBinaryFile[5];
    if(pbin == NULL)
        return 0;

    Viss(2);
    delete [] pbin;

    Viss(3);
    pbin = new CBinaryFile[5](bin);
    if(pbin == NULL)
        return 0;

    Viss(4);
    delete [] pbin;

    Viss(5);
    pbin = new CBinaryFile(bin)[5];
    if(pbin == NULL)
        return 0;

    Viss(6);
    delete [] pbin;

    Viss(7);

    return 0;
}
エラーコード
TestFile.cpp(24) : error C2538: new : 配列に対し初期化子が与えられています。
    pbin = new CBinaryFile[5](bin);

TestFile.cpp(32) : error C2143: 構文エラー : ';' が '[' の前に必要です。
    pbin = new CBinaryFile(bin)[5];

 やはり、配列で確保するときに引数付きのコンストラクタは使えないようですね。


 以上をまとめると、


となります。

 次回も動的確保について話したいと思います。アップキャストと併せたときにどうなるか...ということです。

 それでは、次回まで。


第18章 ピュア | 第20章 デストラクタ(仮)

Last update was done on 2000.8.26

この講座の著作権はロベールが保有しています