概要

  • メモリ確保を行うクラスの継承のサンプル。
  • メモリ確保を行うクラスは、デストラクタ、コピーコンストラクタ、代入演算子オーバーロードの実装が必要。
  • 派生クラスのコンストラクタでは、明示しない場合は基底クラスのデフォルトコンストラクタが呼ばれるため、特殊な初期化が必要な場合はコンストラクタを明示的に呼ぶ必要がある。
  • 派生クラスの代入演算子オーバーロードでは、基底クラスの代入演算子は継承されないため、明示的に呼ぶ必要がある。

ソース

  • &ref(): File not found: "InheritingMallocClass.zip" at page "VisualC++/InheritingMallocClass";

Base.h

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 
 
 
 
 
 
 
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
#pragma once
 
#include <tchar.h>
#include <memory>
 
#define    OUTPUT_BUFFER_COUNT    (1024)
 
class Base {
public:
    virtual ~Base(void);    ///< デストラクタ
 
    Base(void);                ///< デフォルトコンストラクタ
 
    /**
		名前を元に初期化
	*/
    Base(
        _TCHAR *name        ///< 名前
    );
 
    /**
		コピーコンストラクタ
	*/
    Base(
        const Base &rhs        ///< コピー元
    );
 
    /**
		代入演算子オーバーロード
	*/
    Base &operator =(
        const Base &rhs        ///< [in] 代入元
    );
 
    /**
		インスタンスを文字列化
	*/
    virtual _TCHAR *ToString(void);
 
protected:
    size_t _nameCount;
    _TCHAR *_namePtr;
    _TCHAR _outputBuffer[OUTPUT_BUFFER_COUNT];
};

Base.cpp

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
|
!
 
 
 
 
 
-
|
|
|
!
 
 
 
 
 
 
 
-
|
|
-
|
!
!
 
 
 
 
 
 
 
-
|
|
-
|
!
!
 
 
 
-
|
|
|
|
-
|
|
|
!
|
!
 
-
|
|
|
-
|
!
|
!
#include "StdAfx.h"
#include <Windows.h>
#include <string.h>
#include "Base.h"
#include "DebugLog.h"
 
// 「配列 'xxx' の要素は既定で初期化されます」を抑制
#pragma warning (disable : 4351)
 
const _TCHAR nameDefault[] = _T("John");
const _TCHAR nameTitle[] = _T("Name:");
 
Base::~Base(void)
{
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    delete[] _namePtr;    _namePtr = NULL;
}
 
Base::Base(void):
    _nameCount(_countof(nameDefault)),
    _namePtr(new _TCHAR[_nameCount]),
    _outputBuffer()
{
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    SecureZeroMemory(_namePtr, _nameCount * sizeof(_TCHAR));
    _tcscpy_s(_namePtr, _nameCount, nameDefault);
}
 
Base::Base(
    _TCHAR *name
):
    _nameCount(_tcslen(name) + 1),
    _namePtr(new _TCHAR[_nameCount]),
    _outputBuffer()
{
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    SecureZeroMemory(_namePtr, _nameCount * sizeof(_TCHAR));
    if ( _nameCount > 0 ){
        _tcscpy_s(_namePtr, _nameCount, name);
    }
}
 
Base::Base(
    const Base &rhs
):
    _nameCount(rhs._nameCount),
    _namePtr(new _TCHAR[_nameCount]),
    _outputBuffer()
{
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    SecureZeroMemory(_namePtr, _nameCount * sizeof(_TCHAR));
    if ( _nameCount > 0 ){
        _tcscpy_s(_namePtr, _nameCount, rhs._namePtr);
    }
}
 
Base &Base::operator =(
    const Base &rhs
){
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    if (this == &rhs){ return *this; }
    delete[] _namePtr;    _namePtr = NULL;
    _nameCount = rhs._nameCount;
    if ( _nameCount > 0 ){
        _namePtr = new _TCHAR[_nameCount];
        SecureZeroMemory(_namePtr, _nameCount * sizeof(_TCHAR));
        _tcscpy_s(_namePtr, _nameCount, rhs._namePtr);
    }
    return *this;
}
 
_TCHAR *Base::ToString(void){
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    SecureZeroMemory(_outputBuffer, OUTPUT_BUFFER_COUNT * sizeof(_TCHAR));
    _tcscpy_s(_outputBuffer, nameTitle);
    if ( _namePtr ){
        _tcscat_s(_outputBuffer, _namePtr);
    }
    return _outputBuffer;
}

DerivA.h

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 
 
 
 
 
 
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
#pragma once
 
#include "Base.h"
 
typedef std::unique_ptr<_TCHAR[]> uptca;
 
class DerivA : public Base {
public:
    virtual ~DerivA(void);    ///< デストラクタ
 
    DerivA(void);            ///< デフォルトコンストラクタ
 
    /**
		名前を元に初期化
	*/
    DerivA(
        _TCHAR *name,        ///< 名前
        _TCHAR *title        ///< 役職
    );
 
    /**
		コピーコンストラクタ
	*/
    DerivA(
        const DerivA &rhs    ///< コピー元
    );
 
    /**
		代入演算子オーバーロード
	*/
    DerivA &operator =(
        const DerivA &rhs    ///< [in] 代入元
    );
 
    /**
		インスタンスを文字列化
	*/
    _TCHAR *ToString(void);
 
private:
    uptca _title;
};

DerivA.cpp

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 
 
 
 
 
 
 
 
-
|
!
 
 
 
-
|
!
 
 
 
 
 
 
 
-
|
|
|
|
!
 
 
 
 
 
-
|
|
!
 
 
 
-
|
|
|
|
|
!
 
-
|
|
|
|
-
|
!
|
!
#include "StdAfx.h"
#include <Windows.h>
#include "DerivA.h"
#include "DebugLog.h"
 
const _TCHAR titleTitle[] = _T("Title:");
 
DerivA::~DerivA(void)
{
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
}
 
DerivA::DerivA(void):
    _title()
{
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
}
 
DerivA::DerivA(
    _TCHAR *name,
    _TCHAR *title
):
    Base(name),
    _title(new _TCHAR[_tcslen(title) + 1])
{
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    size_t titleSize = _tcslen(title) + 1;
    SecureZeroMemory(_title.get(), titleSize);
    _tcscpy_s(_title.get(), titleSize, title);
}
 
DerivA::DerivA(
    const DerivA &rhs
):
    _title(new _TCHAR[_tcslen(rhs._title.get()) + 1])
{
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    _tcscpy_s(_title.get(), _tcslen(rhs._title.get()) + 1, rhs._title.get());
}
 
DerivA &DerivA::operator =(
    const DerivA &rhs
){
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    size_t titleSize = _tcslen(rhs._title.get()) + 1;
    _title.reset(new _TCHAR[titleSize]);
    _tcscpy_s(_title.get(), titleSize, rhs._title.get());
    return *this;
}
 
_TCHAR *DerivA::ToString(void){
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    Base::ToString();
    _tcscat_s(_outputBuffer, _T("\t"));
    _tcscat_s(_outputBuffer, titleTitle);
    if ( _title ){
        _tcscat_s(_outputBuffer, _title.get());
    }
    return _outputBuffer;
}

DerivB.h

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 
 
 
 
 
 
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
#pragma once
 
#include "Base.h"
 
typedef std::unique_ptr<_TCHAR[]> uptca;
 
class DerivB : public Base {
public:
    virtual ~DerivB(void);    ///< デストラクタ
 
    DerivB(void);            ///< デフォルトコンストラクタ
 
    /**
		名前を元に初期化
	*/
    DerivB(
        _TCHAR *name,        ///< 名前
        _TCHAR *title        ///< 役職
    );
 
    /**
		コピーコンストラクタ
	*/
    DerivB(
        const DerivB &rhs    ///< コピー元
    );
 
    /**
		代入演算子オーバーロード
	*/
    DerivB &operator =(
        const DerivB &rhs    ///< [in] 代入元
    );
 
    /**
		インスタンスを文字列化
	*/
    _TCHAR *ToString(void);
 
private:
    uptca _title;
};

DerivB.cpp

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 
 
 
 
 
 
 
 
-
|
!
 
 
 
 
-
|
!
 
 
 
 
 
 
 
-
|
|
|
|
!
 
 
 
 
 
 
-
|
|
!
 
 
 
-
|
|
|
|
|
|
!
 
-
|
|
|
|
-
|
!
|
!
#include "StdAfx.h"
#include <Windows.h>
#include "DerivB.h"
#include "DebugLog.h"
 
const _TCHAR titleTitle[] = _T("Title:");
 
DerivB::~DerivB(void)
{
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
}
 
DerivB::DerivB(void):
    Base(),
    _title()
{
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
}
 
DerivB::DerivB(
    _TCHAR *name,
    _TCHAR *title
):
    Base(name),
    _title(new _TCHAR[_tcslen(title) + 1])
{
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    size_t titleSize = _tcslen(title) + 1;
    SecureZeroMemory(_title.get(), titleSize);
    _tcscpy_s(_title.get(), titleSize, title);
}
 
DerivB::DerivB(
    const DerivB &rhs
):
    Base(rhs),
    _title(new _TCHAR[_tcslen(rhs._title.get()) + 1])
{
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    _tcscpy_s(_title.get(), _tcslen(rhs._title.get()) + 1, rhs._title.get());
}
 
DerivB &DerivB::operator =(
    const DerivB &rhs
){
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    Base::operator=(rhs);
    size_t titleSize = _tcslen(rhs._title.get()) + 1;
    _title.reset(new _TCHAR[titleSize]);
    _tcscpy_s(_title.get(), titleSize, rhs._title.get());
    return *this;
}
 
_TCHAR *DerivB::ToString(void){
    DEBUG_FUNC_NAME(DebugLevel_DetailInfo);
    Base::ToString();
    _tcscat_s(_outputBuffer, _T("\t"));
    _tcscat_s(_outputBuffer, titleTitle);
    if ( _title ){
        _tcscat_s(_outputBuffer, _title.get());
    }
    return _outputBuffer;
}

Main.cpp

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 
 
 
 
 
 
 
 
 
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
// Main.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
 
#include "stdafx.h"
#include "Base.h"
#include "DerivA.h"
#include "DerivB.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
    Base base1;                    // デフォルトコンストラクタ
    _tprintf_s( _T("%s\n"), base1.ToString() );
 
    Base base2(_T("Jane"));        // 引数ありコンストラクタ
    _tprintf_s( _T("%s\n"),    base2.ToString() );
 
    Base base3(base2);            // コピーコンストラクタ
    _tprintf_s( _T("%s\n"), base3.ToString() );
 
    Base base4 = base2;            // コピーコンストラクタ
    _tprintf_s( _T("%s\n"), base4.ToString() );
 
    Base base5;                    // デフォルトコンストラクタ
    base5 = base2;                // 代入演算子オーバーロード
    _tprintf_s( _T("%s\n"), base5.ToString() );
 
    DerivA derivA1( _T("Johnny"), _T("Manager") );    // 引数ありコンストラクタ
    _tprintf_s( _T("%s\n"), derivA1.ToString() );
 
    DerivA derivA2(derivA1);    // コピーコンストラクタ
    _tprintf_s( _T("%s\n"), derivA2.ToString() );
 
    DerivA derivA3;
    derivA3 = derivA1;            // 代入演算子オーバーロード
    _tprintf_s( _T("%s\n"), derivA3.ToString() );
 
    DerivB derivB1( _T("Jennifer"), _T("CEO") );    // 引数ありコンストラクタ
    _tprintf_s( _T("%s\n"), derivB1.ToString() );
 
    DerivB derivB2(derivB1);    // コピーコンストラクタ
    _tprintf_s( _T("%s\n"), derivB2.ToString() );
 
    DerivB derivB3;
    derivB3 = derivB1;            // 代入演算子オーバーロード
    _tprintf_s( _T("%s\n"), derivB3.ToString() );
 
    return 0;
}

出力

Name:John
Name:Jane
Name:Jane
Name:Jane
Name:Jane
Name:Johnny     Title:Manager
Name:John       Title:Manager
Name:John       Title:Manager
Name:Jennifer   Title:CEO
Name:Jennifer   Title:CEO
Name:Jennifer   Title:CEO

リロード   新規 下位ページ作成 編集 凍結 差分 添付 コピー 名前変更   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: Mon, 17 Feb 2014 01:31:30 JST (1433d)