Win98SP無し/VC++6SP無し
// shift_jis.h
class CShiftJIS
{
public:
friend CShiftJIS operator +(CShiftJIS& r,char* p);
};
// shift_jis.cpp
CShiftJIS operator +(CShiftJIS& r,char* p)
{
}
ShiftJISを扱うstringみたいなクラスを作ってたんですけど
多項のoperator +で上記のもので一応成功したんですけど
何でクラスメンバなのに外部に書かないとダメなんですか?
それと
class CShiftJIS
{
public:
friend CShiftJIS operator +(CShiftJIS& r,char* p) {} // ←ここ
};
これでもOKだっていうので更にわけがわかんなくなりました。
friendってのはこういうものなんですか?
外部に書かないとダメということはありません。
外部に書いた場合、クラスのオブジェクトが複数生成された場合でも、関数本体はメモリに1つ
ですが、
内部に書いた場合は、それが呼び出されるたびに、マクロのようにその位置に展開されます。
短いコードならば内部に書いたほうが実行速度が速くなります。
逆に長いコードを関数を内部に書くと、プログラムサイズが肥大化します。
friend は関係ないと思いますが。
> class CShiftJIS
> {
> public:
> friend CShiftJIS operator +(CShiftJIS& r,char* p);
> };
そのグローバル関数がフレンド関数であることを宣言しているだけであって、
メンバ関数の宣言ではありません。
{} でもコンパイル通るとは知りませんでした。(中身書いたらどうなるんでしょうね。)
> CShiftJIS operator +(CShiftJIS& r,char* p)
> {
> }
ほんとにメンバ関数ならこれではおかしいですよね。
紛れもなくグローバル関数です。
> 内部に書いた場合は、それが呼び出されるたびに、マクロのようにその位置に展開されます。
inline関数じゃないのにですか?
> そのグローバル関数がフレンド関数であることを宣言しているだけであって、
> メンバ関数の宣言ではありません。
だいたいわかりました。そもそも多項のoperatorはメンバには持てませんね。
というかfriend宣言をする意味があるんですかね?
べつにクラスの外に普通に関数プロトタイプを書くだけでいいような気がするんですけど。
それともこのクラスで使ってるってのをわかりやすくするためですかね?
>外部に書いた場合、クラスのオブジェクトが複数生成された場合でも、
>関数本体はメモリに1つですが、
外部に書いた場合でも「inline宣言があり、後方参照がされてる」なら、
inline展開されます。
>inline関数じゃないのにですか?
インライン関数です。
>というかfriend宣言をする意味があるんですかね?
この例では有りません。しかし下記のような時はfriendにする以外の解決方法はありません。
abc + CShiftJIS_Object; // ※ CShiftJIS_ObjectはSShiftJIS型変数
CShiftJISに変換コンストラクタがあればfriendにしなくてもできます。
しかし理由が無い限りこうはしません。オーバーヘッドの為です。
>>inline関数じゃないのにですか?
>インライン関数です。
inline宣言をしてないのに勝手にinlineになるような機能があるんですか?
それと..
CShiftJIS(char* p)
↑変換コンストラクタってこういうのですか?
>inline宣言をしてないのに勝手にinlineになるような機能があるんですか?
>CShiftJIS(char* p)
>↑変換コンストラクタってこういうのですか?
ここからは御自分で調べて下さい。
ファイナルアンサー
> というかfriend宣言をする意味があるんですかね?
> べつにクラスの外に普通に関数プロトタイプを書くだけでいいような気がするんですけ
> ど。
その通りです。単なるグローバル関数でも構いません。
friend 宣言するのは private なメンバにアクセスできるようにするためです。
他意はありません。
試してみたらグローバル関数でも平気でした。