#pragma twice

KAB-studio > プログラミング > #pragma twice > 346 Version 16.19 型変換演算子のオーバーロード

#pragma twice 346 Version 16.19 型変換演算子のオーバーロード

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

 Version 16.19
型変換演算子のオーバーロード

今回は最後のオーバーロード、型変換演算子のオーバーロードについて説
明します
一度やってるんだよね
 Version 11.20 ( No.220 ) で説明したけど、今回はその復習。まずは例
から

// Data.h

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

    // 型変換演算子のオーバーロード。
    operator int();
};

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

#include "Data.h"

// 型変換演算子のオーバーロード。
CData::operator int()
{
    return m_iData;
}

// 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.m_iData = 100;

    // 型変換演算子のオーバーロードを使用します。
    int i = cData;

    char pch[256];
    sprintf( pch, "%d\n", i );
    OutputDebugString( pch );
    // 100

    return 0;
}

まず、【型変換演算子】っていうのは、具体的に言うとキャストのこと
キャストって、 (int)i とかのキャスト?
それもそうだし、そうはっきりと書かないキャストも含みます
はっきり書かないキャスト?
たとえば int 型の変数に char 型の値を代入したときとか、そういう、
型は違うんだけど変換して渡せる、そういうものもキャストに含むんです
そういうキャストも全部ひっくるめて、型変換演算子、って言うと?
そういうこと。演算子、っていうのには抵抗あるかもしれないけどね
うん、抵抗ある
変数の値に対して何らかの処理をして結果を返す、っていう点では演算子
なんだよね。演算子の性質としては、 ! 演算子とかが近いかも
 TRUE と FALSE を入れ替える?
そう。あれと同じ、値を変換して返す、そういう意味での演算子
うーん、なんかちょっと納得いかないけど……
まぁ名前の問題だから、それほど深く考えなくてもいいかも。今回の例で
は、以下の箇所が、型変換演算子を使用している箇所になります

    // 型変換演算子のオーバーロードを使用します。
    int i = cData;

 CData クラスの変数から int 型の変数に代入しようとしているので、
コンパイラは CData から int へ型変換しようとします
でも普通できないよね
そう、できません。そこで、型変換演算子をオーバーロードします。以下
のメンバ関数が、 int 型の型変換演算子のオーバーロードです

// 型変換演算子のオーバーロード。
CData::operator int()
{
    return m_iData;
}

な、なんかこれまた変な書き方だよね……
書き方は、以下のようになります

クラス::operator 型()

こうすると、〈クラス〉が〈型〉に変換されようとしたときに、この
メンバ関数が呼び出されます
 m_iData を返すって事は、その値が i に渡されるんだ
そういうこと。こんな感じに、型変換演算子のオーバーロードは〈ただひ
とつだけメンバ変数を持っていて、それが目に見えて分かる〉ような場合に
だけ作るような感じかな
どゆこと?
メンバ変数がふたつあったら?
……どっち返せばいいかわからないね
でしょう。それよりは、 CString クラスみたいに
何返すのか分かり切ってる!
っていうクラスの方が型変換演算子のオーバーロードを使うのに向いてい
る、ってこと
なるほどねー。……? 質問!
はい火美ちゃん
これってメンバ関数だけど、普通の関数にはできる?
ううん、できません。まだ説明していなかったけど、 = 演算子とか、こ
の型変換演算子は、メンバ関数としてしか作れないんです
げ、そうなんだ
だから

operator int( CData &p_rcData )
{
    return p_rcData.m_iData;
}

みたいなのは作れません
なるほど、じゃあ次の質問!
はい火美ちゃん
さっきの使ってるとこ見て思ったんだけど

    // 型変換演算子のオーバーロードを使用します。
    int i = cData;

これって、わざわざ型変換演算子のオーバーロードしなくても、 
= 演算子のオーバーロードしちゃえばいいんじゃない?
さっき説明したけど
あ”、そういえばそうだね、 = 演算子はメンバ関数じゃないといけない
けど、そしたら int 型のメンバ関数にしなきゃいけなくて……無理だね
それ以前に、この例は = 演算子を使っているけど、 int 型変数を宣言し
ているわけだから、実際には……

つまり、こういうこともできるから

    // 型変換演算子のオーバーロードを使用します。
    int i( cData );

あ! そうだった、コンストラクタ呼んでるんだ!
そういうこと。変数の初期化をするときの = 演算子は、実際には引数が
1つのコンストラクタを呼び出しているのと同じこと
 Version 16.12 ( No.339 ) でやったのだ
だから、 = 演算子じゃなくて、コンストラクタの話として考えなきゃい
けないわけ
あー。……でも、 int 型のコンストラクタとか作れないし
 int 型ならね。でも普通のクラスなら
作れちゃう……? じゃあさじゃあさ、その普通のクラスのコンストラクタ
で CData クラス受け取ってさ、 CData クラスでは……あれ?
うん、つまり、その普通のクラスを CData2 だとすると

    // 型変換演算子のオーバーロードを使用します。
    CData2 cData2 = cData;

ってした時に、 CData2( CData &p_rcData ) が呼ばれるのか、
CData::operator CData2() が呼ばれるのか分からない、ってことでしょ?
……??? なんだかよく分からなくなってきた
……というわけで次回に続く
ええっ!?

/*
    Preview Next Story!
*/
なんで続くのー?
実は、これはとても重要な問題なんです
そなの? ちょっと思い付いただけなんだけど
そういうところが重要なんだよね、実は
意外
というわけで次回
< Version 16.20 オーバーロードの選択 >
につづく!
逆に、気付かないと実はすごくまずいという
う”、意外意外
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。