#pragma twice

KAB-studio > プログラミング > #pragma twice > 341 Version 16.14 コンストラクタのオーバーロード

#pragma twice 341 Version 16.14 コンストラクタのオーバーロード

前のページへ 表紙・目次へ 次のページへ

 Version 16.14
コンストラクタのオーバーロード

前回はオーバーロードについて説明しました
関数は、同じ名前で引数の違う関数を作れる、と
そして渡した引数でどの関数が呼ばれるかが決まる、というわけです
それだけなら簡単よね
それだけなら、ね
う”
というわけで、まずはコンストラクタのオーバーロードについて説明しま

コンストラクタのオーバーロード、引数の違うコンストラクタ……ん?
そう、実はこれまでの例で何度も出てきています。ここまでで説明してき
たコンストラクタの復習も兼ねて見ていきます

// Data.h

// CDataクラス。
class CData
{
public:
    // private メンバ変数。
    int m_iData;

public:
    // 引数のないコンストラクタ。
    CData();
    // コピーコンストラクタ。
    CData( const CData &p_rcData );
    // 引数が int 型のコンストラクタ。
    CData( int p_i );
    // 引数が int 型2つのコンストラクタ。
    CData( int p_i1, int p_i2 );
};


// Data.cpp
#include <Windows.h>
#include <stdio.h>

#include "Data.h"

// 引数のないコンストラクタ。
CData::CData()
    : m_iData( 0 )
{
}

// コピーコンストラクタ。
CData:: CData( const CData &p_rcData )
    : m_iData( p_rcData.m_iData )
{
}

// 引数が int 型のコンストラクタ。
CData::CData( int p_i )
    : m_iData( p_i )
{
}

// 引数が int 型2つのコンストラクタ。
CData::CData( int p_i1, int p_i2 )
    : m_iData( p_i1 + p_i2 )
{
}


全部で4つのコンストラクタがあります

・引数のないコンストラクタ
・コピーコンストラクタ
・引数が int 型のコンストラクタ
・引数が int 型2つのコンストラクタ

あれ? デフォルトコンストラクタはないの?
ないよ
……あー、そりゃそうだよね、コンストラクタ作ったらなくなっちゃうん
だから
そういうこと。デフォルトコンストラクタは〈コンストラクタがない時に
だけ存在する見えないコンストラクタ〉だから、コンストラクタがあったら
ないし、あっても見えないから
ここに出てくるわけないね……
話を戻すと、このようにコンストラクタも、他のメンバ関数と同じように
オーバーロードすることができます
でも、コンストラクタって関数を呼ぶ、って感じじゃないからいまいち
実感が沸かないかも
それは言えるかもね。使用例はこうなります

// Main.cpp
#include <Windows.h>
#include <stdio.h>

#include "Data.h"
int WINAPI WinMain
    ( HINSTANCE p_hInstance
    , HINSTANCE p_hPrevInstance
    , LPSTR p_pchCmdLine
    , int p_iCmdShow
    )
{
    // CData クラスの変数を宣言します。
    // 引数のないコンストラクタを呼び出します。
    CData cData;
    // コピーコンストラクタを呼び出します。
    CData cData2( cData );
    // int 型引数を持つコンストラクタを呼び出します。
    CData cData3( 100 );
    // int 型引数2つを持つコンストラクタを呼び出します。
    CData cData4( 100, 200 );

    return 0;
}

渡す初期値によって、コンストラクタが変わる感じかな

・何も渡さない               → 引数のないコンストラクタ
・同じクラス                 → コピーコンストラクタ
・int型変数や整数リテラル    → 引数が int 型のコンストラクタ
・int型変数や整数リテラル2つ → 引数が int 型2つのコンストラクタ

このように、何を渡すかによって呼ばれるコンストラクタが変わることに
なります
これも、他のオーバーロードと同じように、渡した型に近いものが選ばれ
るの?
そう。型が同じならその方、ないなら近い型のメンバ関数が呼ばれます。
どれか分からない場合にはコンパイルエラーになります
前回のと同じってわけね。……質問!
はい火美ちゃん
引数のないコンストラクタを呼んでる所って、こうじゃダメ?

    // 引数のないコンストラクタを呼び出します。
    CData cData();

だめなんです

    CData cData();
    // コンパイルエラー:
    // error C2664: '__thiscall CData::CData(const class CData &)' : 
    // 1 番目の引数を 'class CData (__cdecl *)(void)' から 
    // 'const class CData &' に変換できません。 
    // 理由: 'class CData (__cdecl *)(void)' から 'const class CData' 
    // へは変換できません。
    // コンストラクタはソース型を持てません、またはコンストラクタの
    // オーバーロード レゾリューションがあいまいです。

な、なんかよく分からないエラーが……
実際、これはできるようにして欲しかったんだけど、仕様上できないんだ
よね。だから諦めるしかないかな
むー……あ、もうひとつ質問!
はい火美ちゃん
 = 使ってもできるんだよね、コンストラクタ呼ぶの
はいできます

// Main.cpp
#include <Windows.h>
#include <stdio.h>

#include "Data.h"
int WINAPI WinMain
    ( HINSTANCE p_hInstance
    , HINSTANCE p_hPrevInstance
    , LPSTR p_pchCmdLine
    , int p_iCmdShow
    )
{
    // CData クラスの変数を宣言します。
    // デフォルトコンストラクタを呼び出します。
    CData cData;
    // コピーコンストラクタを呼び出します。
    CData cData2 = cData;
    // int 型引数を持つコンストラクタを呼び出します。
    CData cData3 = 100;
    // int 型引数2つを持つコンストラクタを呼び出します。
    CData cData4( 100, 200 );

    return 0;
}

このように、引数がひとつのコンストラクタのみ、 = 演算子で初期化す
ることができます。してることは、さっきの例と同じだからね
これでコンストラクタが呼ばれるっていうのも不思議だよね……
 C++言語の仕様は不思議なところ多いからね
だよね、コピーコンストラクタだって、とっても特別なコンストラクタ
って気がするんだけど、なんか他のコンストラクタと同じような感じだよ

そういうものが多いかも。普通のプログラムのように見えて、特別な意味
があるあるものとか
そういうのがよく分からない……
それはもう、片っ端から試してみて、コンパイルエラーを取り除きながら
憶えていくしかないかもね
う”……

/*
    Preview Next Story!
*/
こういう、特別な意味のって難しい……
普通のメンバ関数に見えるからね
そうそう。少し違うとダメだし、憶えてないといけないし
その一番典型的な例が演算子のオーバーロードかな
あーあれもよく分からなかった!
というわけで次回
< Version 16.15 演算子のオーバーロードの復習 >
につづく!
復習だけど、コンストラクタの例とかを踏まえつつ、だといいかも
そういえばそういうとこ似てる感じ……?
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。