ヘッダファイルについて

解決


初心者  2008-04-03 03:47:35  No: 67948

VC++を使い、C++でプログラムの勉強を始めたのですが
あるサイトで公開しているソースを見てみると
ヘッダファイルにプログラムが書かれてました。
このような感じです。

class CTest{
private:
    HANDLE hnd;

public:
    Test(void);
    virtual ~Test(void);

};

// コンストラクタ
CTest::CTest(void):
hnd(NULL){
}

// デストラクタ
CTest::~CTest(void){
}

HANDLE CTest::getHandel(void){
   return this->hnd;
}

ヘッダに記述する場合とソースファイルに記述する場合で
なにか変わるものなのでしょうか。
私的には、コンストラクタ以降の実装部分はソースファイルに
記述したいと考えています。色々とネット検索したのですが
ヘッダに記述する利点が良く分かりません。
よろしくお願いします。


επιστημη  URL  2008-04-03 06:20:17  No: 67949

templateとinlineでない限り、ヘッダに実装してはいけません。


初心者  2008-04-08 00:51:56  No: 67950

>επιστημηさん

ヘッダに書いたのは公開ソースだからでしょうかね。。

ヘッダとソース分けて書くようにします

ありがとうございました。


επιστημη  URL  2008-04-08 01:38:18  No: 67951

> ヘッダに書いたのは公開ソースだからでしょうかね。。

いえ、きっと"誤り"です。
さもなくば、そのヘッダを#includeするのが唯一ひとつであるか。


ひろ  2008-04-08 03:38:38  No: 67952

もう見てないかな。

> HANDLE CTest::getHandle(void){
>    return this->hnd;
> }

これに関して言えば、inlineとしているのだと思います。

ここなどを参考にしてみてください。
http://mikata.curiocube.com/oop/part3/ch02_encapsulation.html


ひろ  2008-04-08 03:40:41  No: 67953

補足

class CTest
{

};

★この中で
HANDLE getHandel(void){
   return this->hnd;
}
こう書いたほうがいいでしょうが。。


επιστημη  URL  2008-04-08 04:43:00  No: 67954

>> HANDLE CTest::getHandle(void){
>>    return this->hnd;
>> }
>
> これに関して言えば、inlineとしているのだと思います。

なにを根拠に?


ひろ  2008-04-08 17:20:49  No: 67955

> なにを根拠に?

一般的に。


あー  2008-04-08 18:16:23  No: 67956

質問者の提示したコードは明らかにinlineでは無いのだが


ひろ  2008-04-08 18:22:24  No: 67957

まぁコンパイルが通るものではないからねぇ。


アキラ  URL  2008-04-08 18:22:49  No: 67958

クラス定義外でinline化するなら
こうしないといけないのではないでしょうか

class CTest {
    HANDLE getHandel(void);
};

inline HANDLE CTest::getHandel(void)
{
    return this->hnd;
}

http://www.geocities.jp/ky_webid/cpp/language/021.html


あー  2008-04-08 18:26:09  No: 67959

inlineと推測した理由になってない


ひろ  2008-04-08 18:45:32  No: 67960

アキラさんへ

class CTest {
    HANDLE hnd;
    HANDLE getHandle(void)
    {
        return hnd;
    }
};
これでいいと思います。

> inlineと推測した理由になってない

だから一般的に。


ひろ  2008-04-08 18:52:04  No: 67961

> クラス定義外でinline化するなら

ごめん、間違えた。
そうですね。


アキラ  URL  2008-04-08 18:54:05  No: 67962

>これでいいと思います。
私が言っているのはクラス定義内ではなくクラス定義外の話です。

> HANDLE CTest::getHandle(void){
>    return this->hnd;
> }
これはinlineではありません


アキラ  URL  2008-04-08 18:55:08  No: 67963

>ごめん、間違えた。
>そうですね。
すいません、↑のコメントを見るまえに書きました


あー  2008-04-08 19:07:09  No: 67964

オレも何度かヘッダに実装書いてるミスを見てきてるし、このトピック内でも少なくとも2人が投稿者の改変ミスではなく元コードの誤りと判断している
元コードを書いた奴がinlineを意図していたと見るのは全然一般的じゃないな


初心者  2008-04-09 20:05:53  No: 67965

気付きませんでした。。。申し訳ないです。。

提示したコードの元コードには、inline、templateの表記は
ありませんでした。

ちょっと話しがそれて恐縮なのですが。
VisualStudio2005のVC++を現在使ってるのですが、そこで
フォームを追加すると、自動でヘッダファイルが作られ、
そこにコードが全て書かれるのです。

サイトの内容と、VS2005の状態を見て、実際どうすればいいのか
混乱してしまい今回質問させて頂きました。

結論としては、ヘッダにコードを記述してincludeすることは可能だが
特殊な事情でもないかぎりはやるべきではない・・・ってことですね。

色々とコメントありがとうございました。


tetrapod  2008-04-09 20:44:31  No: 67966

フォーム?  フォームアプリケーションなの?それとも MFC なの?
それともまったく違う何か?

俺の手元の VS2005+MFC のクラスウィザードでは、クラスの新規作成で
ヘッダに非インラインなコードを自動生成したりはしないよ

何か大きく勘違いしている可能性あり


山口  2008-04-09 21:33:35  No: 67967

初心者さん
> VisualStudio2005のVC++を現在使ってるのですが、そこで
> フォームを追加すると、自動でヘッダファイルが作られ、
> そこにコードが全て書かれるのです。
先に回答されているεπιστημηさんが、まさにこの点を↓にて指摘されていますね。併せて参照してみてください。
http://www.atmarkit.co.jp/fdotnet/special/vcppinvista02/vcppinvista02_01.html

ここで便乗質問させてください。
「C言語ベースのライブラリ関数を単純に分類・ラッピングのためだけにクラスを導入した場合、
つまりクラスを(inlineで)マクロ的にのみ使用したい場合でも、クラス実装をヘッダに記載する方法はダメなのか?」

まず、επιστημηさんも指摘されている、
  本来「宣言」のみが目的のヘッダに「実装」まで記載すると、「実装のみの変更」時にも
  そのヘッダを参照する全ソースに再コンパイルを要求することになり、結果ソースの保守性を著しく悪化させる。
という点は一応理解しているつもりです。

で、私の質問ですが、例えば Win32 API がわかりやすいかと思いますが、
一例としてMutex関連のAPI関数をまとめてハンドルを隠蔽化する目的で、Mutexクラスを自作したとします。
class Mutex
{
protected:
  m_handle;
public:
  BOOL Release()
  {
    return ReleaseMutex( m_handle );
  }
};
のような感じで…。こうして自作したクラスは
・各メソッドはAPI関数にほとんどそのまま1:1で対応する。
・実装内容(対応する関数呼び出し)は、まず変更することは無い。
という点から、上記のように 宣言・定義 をまとめたヘッダファイル Mutex.hpp を用意します。

そして、自作アプリからは
  #include <windows.h>
のかわりに
  #include <Mutex.hpp>
のように使用します。

こういう使い方はNGなのでしょうか?
一応επιστημηさんのご回答
> templateとinlineでない限り、ヘッダに実装してはいけません。
のinlineには該当しているかと思うのですが…

−以上−


初心者  2008-04-09 22:17:47  No: 67968

tetrapodさん

フォームアプリケーションです。説明不足で申し訳ないです。
自動で生成されるゆえにこれが一般的なのか?と思ってしまいます。。

山口さん

おぉぉ!
それです。サイト早速読ませて頂きました(まだ最初のほうだけですが)。
やはりVS2005は紛らわしいってことですかね。。

ありがとうございました。


アキラ  URL  2008-04-09 23:21:23  No: 67969

> 山口さん
そこまで理解したうえでやるならかまわないと思います。
私もけっこうやりますよ。(inline のみの簡単なクラス)


PATIO  2008-04-10 02:36:20  No: 67970

フォームアプリなら
C++ではなくてC++/CLIなのでそもそも言語的に別物ですし。

確かにC++/CLIでVisualStudioが吐き出す雛形はヘッダに
コードも入るみたいですね。


初心者  2008-04-10 03:37:21  No: 67971

PATIOさん

C++/CLIを単にC++拡張版と勘違いしていたようです。。
お恥ずかしい。。

ありがとうございました。


アキラ  URL  2008-04-10 18:43:06  No: 67972

> 山口さん
インラインのみのクラスですが、仮想関数も全てインラインになっていると
コンパイラによってはまずいかもしれません。
http://d.hatena.ne.jp/faith_and_brave/20070719/1184848286


山口  2008-04-16 10:33:50  No: 67973

※アキラさん、レスが遅れて申し訳ありません。
> インラインのみのクラスですが、仮想関数も全てインラインになっていると
> コンパイラによってはまずいかもしれません。
ご紹介リンク先確認しました。了解です。

手元に More でない『Effective C++ 改訂第2版』がありますが、
この第33章でも触れられていますね。改めて確認しています。

ちなみに私の開発環境はもっぱらWindows用のVC++(6.0, 7.1, 8.0), BCC なのですが、
自作クラスライブラリではデストラクタをはじめ何カ所か仮想関数も含んでいますが、
これまでのところ特に問題はないようです。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加