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;
}
ヘッダに記述する場合とソースファイルに記述する場合で
なにか変わるものなのでしょうか。
私的には、コンストラクタ以降の実装部分はソースファイルに
記述したいと考えています。色々とネット検索したのですが
ヘッダに記述する利点が良く分かりません。
よろしくお願いします。
templateとinlineでない限り、ヘッダに実装してはいけません。
>επιστημηさん
ヘッダに書いたのは公開ソースだからでしょうかね。。
ヘッダとソース分けて書くようにします
ありがとうございました。
> ヘッダに書いたのは公開ソースだからでしょうかね。。
いえ、きっと"誤り"です。
さもなくば、そのヘッダを#includeするのが唯一ひとつであるか。
もう見てないかな。
> HANDLE CTest::getHandle(void){
> return this->hnd;
> }
これに関して言えば、inlineとしているのだと思います。
ここなどを参考にしてみてください。
http://mikata.curiocube.com/oop/part3/ch02_encapsulation.html
補足
class CTest
{
★
};
★この中で
HANDLE getHandel(void){
return this->hnd;
}
こう書いたほうがいいでしょうが。。
>> HANDLE CTest::getHandle(void){
>> return this->hnd;
>> }
>
> これに関して言えば、inlineとしているのだと思います。
なにを根拠に?
> なにを根拠に?
一般的に。
質問者の提示したコードは明らかにinlineでは無いのだが
まぁコンパイルが通るものではないからねぇ。
クラス定義外でinline化するなら
こうしないといけないのではないでしょうか
class CTest {
HANDLE getHandel(void);
};
inline HANDLE CTest::getHandel(void)
{
return this->hnd;
}
http://www.geocities.jp/ky_webid/cpp/language/021.html
inlineと推測した理由になってない
アキラさんへ
class CTest {
HANDLE hnd;
HANDLE getHandle(void)
{
return hnd;
}
};
これでいいと思います。
> inlineと推測した理由になってない
だから一般的に。
> クラス定義外でinline化するなら
ごめん、間違えた。
そうですね。
>これでいいと思います。
私が言っているのはクラス定義内ではなくクラス定義外の話です。
> HANDLE CTest::getHandle(void){
> return this->hnd;
> }
これはinlineではありません
>ごめん、間違えた。
>そうですね。
すいません、↑のコメントを見るまえに書きました
オレも何度かヘッダに実装書いてるミスを見てきてるし、このトピック内でも少なくとも2人が投稿者の改変ミスではなく元コードの誤りと判断している
元コードを書いた奴がinlineを意図していたと見るのは全然一般的じゃないな
気付きませんでした。。。申し訳ないです。。
提示したコードの元コードには、inline、templateの表記は
ありませんでした。
ちょっと話しがそれて恐縮なのですが。
VisualStudio2005のVC++を現在使ってるのですが、そこで
フォームを追加すると、自動でヘッダファイルが作られ、
そこにコードが全て書かれるのです。
サイトの内容と、VS2005の状態を見て、実際どうすればいいのか
混乱してしまい今回質問させて頂きました。
結論としては、ヘッダにコードを記述してincludeすることは可能だが
特殊な事情でもないかぎりはやるべきではない・・・ってことですね。
色々とコメントありがとうございました。
フォーム? フォームアプリケーションなの?それとも MFC なの?
それともまったく違う何か?
俺の手元の VS2005+MFC のクラスウィザードでは、クラスの新規作成で
ヘッダに非インラインなコードを自動生成したりはしないよ
何か大きく勘違いしている可能性あり
初心者さん
> 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には該当しているかと思うのですが…
−以上−
tetrapodさん
フォームアプリケーションです。説明不足で申し訳ないです。
自動で生成されるゆえにこれが一般的なのか?と思ってしまいます。。
山口さん
おぉぉ!
それです。サイト早速読ませて頂きました(まだ最初のほうだけですが)。
やはりVS2005は紛らわしいってことですかね。。
ありがとうございました。
> 山口さん
そこまで理解したうえでやるならかまわないと思います。
私もけっこうやりますよ。(inline のみの簡単なクラス)
フォームアプリなら
C++ではなくてC++/CLIなのでそもそも言語的に別物ですし。
確かにC++/CLIでVisualStudioが吐き出す雛形はヘッダに
コードも入るみたいですね。
PATIOさん
C++/CLIを単にC++拡張版と勘違いしていたようです。。
お恥ずかしい。。
ありがとうございました。
> 山口さん
インラインのみのクラスですが、仮想関数も全てインラインになっていると
コンパイラによってはまずいかもしれません。
http://d.hatena.ne.jp/faith_and_brave/20070719/1184848286
※アキラさん、レスが遅れて申し訳ありません。
> インラインのみのクラスですが、仮想関数も全てインラインになっていると
> コンパイラによってはまずいかもしれません。
ご紹介リンク先確認しました。了解です。
手元に More でない『Effective C++ 改訂第2版』がありますが、
この第33章でも触れられていますね。改めて確認しています。
ちなみに私の開発環境はもっぱらWindows用のVC++(6.0, 7.1, 8.0), BCC なのですが、
自作クラスライブラリではデストラクタをはじめ何カ所か仮想関数も含んでいますが、
これまでのところ特に問題はないようです。
ツイート | ![]() |