#pragma twice

KAB-studio > プログラミング > #pragma twice > 333 Version 16.06 インラインメンバ関数

#pragma twice 333 Version 16.06 インラインメンバ関数

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

 Version 16.06
インラインメンバ関数

質問!
はい火美ちゃん
前回、基本的なクラスについて教えてもらいました

// Data.h

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

public:
    // m_iData の getter 。
    int GetData() const;
    // m_iData の setter 。
    void SetData( int p_iData );
};


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

#include "Data.h"

// m_iData の getter 。
int CData::GetData() const
{
    return m_iData;
}

// m_iData の setter 。
void CData::SetData( int p_iData )
{
    m_iData = p_iData;
}

でも、 Version 11.16 ( No.216 ) の時は、こうでした

// メンバ関数を持つクラス。
class CHasMemberFunction
{
private:
    int m_iData;

public:
    // 値を返します。
    int GetData() const
    {
        return m_iData;
    }

    // 値をセットします。
    void SetData( int p_i )
    {
        m_iData = p_i;
    }
};

どっちが正しいんやねん!
そうだね、この使い分けについて説明していなかったね。まず、基本的な
機能は同じ。単純に言えば、書き方の問題、プログラミングスタイルの違い
です
見た目とか、プログラムの癖とかそーゆーこと?
基本的にはね。細かい所はちょっと違うので、それをこれから説明しま

ほい
まず、 Version 11.16 ( No.216 ) の CHasMemberFunction クラスのよう
に、クラスの中に入れられたメンバ関数は【インラインメンバ関数】と言い
ます
いんらいんめんばかんすう……?
そう。このメンバ関数はちょっと特殊で、呼び出し元に関数そのものが埋
め込まれます
埋め込まれる……って、マクロみたいに?
そういうこと。だから、呼び出しがちょっとだけ早くなります
でも、それってファイルサイズ大きくならない?
なります。それに、実際には埋め込まれるとは限らないから
へ?
 Version 15.23 ( No.323 ) で、【関数のインライン展開の制御】ってい
うオプションがあったでしょ
あ! そういえばあの時も関数が埋め込まれるとかどうとか
これをオンにしないと埋め込まれないから、この〈埋め込まれる〉ってい
う機能はおまけとして考えて、あまりこだわらない方がいいかな
つまりそれを目的にして、こんな書き方しない方がいいってことね
そういうこと。じゃあ、メンバ関数を分けるのと分けないの、どちらが
いいのかという点について。まず、分けない場合、通常はヘッダーファイル
に書きます

// Data.h

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

public:
    // m_iData の getter 。
    int GetData() const
    {
        return m_iData;
    }

    // m_iData の setter 。
    void SetData( int p_iData )
    {
        m_iData = p_iData;
    }
};

// Data.cpp
// (空)

このように、ヘッダーファイルの方に全て入れて、ソースファイルの方は
何も書かないようにします
??? それおかしいじゃん。コンパイルはソースファイル単位でするん
だから、こんなことしたらコンパイルされない……んじゃなくて、
インクルードしたソースファイル全部でコンパイルされちゃうんじゃ……
それがされないんです。確かにソースファイルがないとそのオブジェクト
ファイルは作られないんだけど、インラインメンバ関数最初に使用する
ソースファイルでコンパイルしたら、あとはそれを使い回すんです
オブジェクトファイルがなくてもいい……他のオブジェクトファイルに
入ってるってこと?
そういうこと。だから、インラインメンバ関数の場合、ヘッダーファイル
に関数の実装を書ける、ということになります
ヘッダーファイルに書ける……とどうなるの?
ソースファイルが要らなくなります
ソースファイルが要らない……ちょっとそれ楽かも
でしょ。 C++ 言語は、ヘッダーファイルとソースファイルっていう2つの
ファイルでプログラムを管理するから、複雑になりやすいんです
それが、インラインメンバ関数を使えばヘッダーファイルだけになる!
 Java とかの、 C++言語以外のプログラミング言語は1ファイルだけで済
むものがほとんどだから、それに比べて C++言語はとても面倒なんだよね
うん、面倒面倒! この方がずっと楽! なんだ、じゃあ全部
ヘッダーファイルでやればいいんじゃん
実際、そういうふうに書かれたプログラムもあるよ。だから、そういう
流れもあるかも
じゃあ
でも、僕はお勧めしません
ええー?
一番の理由は、相互参照の解決が難しい点
相互参照……ってどっかで聞いたね
 Version 15.05 ( No.305 ) で説明したでしょ。あるヘッダーファイルが
他のヘッダーファイルの機能を使用する時に、順序がうまくいかなくなる、
っていうの
あー
たとえば CData クラスと CData2 クラスが以下のようになっていた場合

// Data.h

// CDataクラス。
class CData
{
public:
    void Output()
    {
        OutputDebugString( "CData::Output()\n" );
    }

    void UseCData2()
    {
        CData2 cData2;
        cData2.Output();
    }
};


// Data2.h

// CData2クラス。
class CData2
{
public:
    void Output()
    {
        OutputDebugString( "CData2::Output()\n" );
    }

    void UseCData()
    {
        CData cData;
        cData.Output();
    }
};

う、両方で使い合ってるね。これじゃ、使う方はどっちを先に
インクルードしてもエラーになるね……
これを解決するためには、定義の部分をソースファイルに移すしかないか
ら、結局ソースファイル使った方がいいかな。
それ以外にもデメリットってある?
結局問題は、定義の中ではいろんな関数やクラスを使う、ってこと。
ヘッダーファイルにそれを書くってことは、そのヘッダーファイルを
インクルードする前に、そういう関数やクラスの宣言が書かれた
ヘッダーファイルをインクルードしなきゃいけないでしょ
そか、ヘッダーファイルをインクルードするために、たくさんの
ヘッダーファイルをインクルードしなきゃいけないんだ
どれをインクルードしなきゃいけないとか、順番も気にしなきゃいけない
でしょ。ソースファイルに書いちゃえば、そのソースファイルで
インクルードすればいいだけだから
確かにその方が簡単そうだね……む、結局そうなっちゃうんだ
 C++言語は元々複雑な言語だから、ちょっと手間が掛かっても、
ソースファイルとヘッダーファイルの両方作った方が分かりやすくなるよ

/*
    Preview Next Story!
*/
うーん、今回のは結構良さそうだったのになー
 C++言語は簡単そうなものも実は複雑だから
他のも? たとえば?
たとえば、ポインタに対する参照とか
あー、参照って簡単に使えるけど、逆にその辺があやふやかも
というわけで次回
< Version 16.07 ポインタと参照のおさらい >
につづく!
クラスをちゃんと理解する上で重要なおさらいです
おさらいはおさらいだと思うけど……
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。