[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2chのread.cgiへ]
Update time : 08/27 18:32 / Filesize : 189 KB / Number-of Response : 742
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【初心者歓迎】C/C++室 Ver.37【環境依存OK】



1 名前:デフォルトの名無しさん mailto:sage [2007/05/06(日) 15:29:45 ]
エスケープシーケンスやWin32APIなどの環境依存な物でもOK。
ただしその場合、質問者は必ず、環境を書きましょう。
※sageは禁止です。
【前スレ】
【初心者歓迎】C/C++室 Ver.36【環境依存OK】
pc11.2ch.net/test/read.cgi/tech/1175436073/
【アップローダー】(質問が長い時はココ使うと便利)
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm


75 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 14:59:30 ]
関数の前にコロンを二つ付けるのは
何の意味があるんでしょうか?

76 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 15:21:14 ]
aが1かそれ以外になるタイミングはプログラマが完全に把握でき、
処理nanntokaが頻繁に起こる場合において、

//hinnpann
if(a==1){
 //nanntoka
}

とするか

//junnbi
void voidfunc(){}//何もしない関数
void nanntokafunc(){ /* nanntoka */ }
void(*pfunc)();//a==1ならnanntokafuncが、それ以外ならvoidfunc

//hinnpann
pfunc();

とするかでは、後者の方が条件判断をしない分早いんですか?
それとも無駄に何もしない関数にジャンプする分だけ遅いんですか?
あと歯を磨くのが面倒くさいので、
手軽に口内の歯垢を生成する菌そのものを除去するオススメの方法って知りませんか?

77 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 15:26:54 ]
>>76
速度は実測が基本。

菌の除去には強酸を使うのはどうだろう?
塩酸とか硫酸とかでよーくうがいすれば、きっと菌なんて生きてられないはず。

78 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 15:27:45 ]
>>75 スコープ解決演算子

79 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 15:32:41 ]
やっぱりCPUによって違いますよね・・・。
「頻繁」とか、曖昧な表現をしてすみませんでした。

塩酸や硫酸は、練り歯磨き粉に入ってる分だけでも痛いのに
リステインなどは泣きそうになるほど厳しいです。
ミュータンス菌も生きるために必死だから、そうそううまい話なんてありませんよね。

80 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 18:11:27 ]
水酸化ナトリウムや水酸化カリウムなんかの強塩基でも菌を破壊できます。

81 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 19:35:17 ]
>>75
グローバルスコープだね。
ローカルと明示的に分ける場合に必要


82 名前:デフォルトの名無しさん mailto:age [2007/05/13(日) 20:29:41 ]
// Foo.h
class Foo {
private:
int a;

public:
static int GetA() const
};

// Foo.cxx
#include "Foo.h"
int Foo::GetA const
{
return a;
}

っていうのは、なんか間違ってますか?
GCCで
./include/Foo.h:6: error: static member function 'static int GetA()' cannot have cv-qualifier
src/Foo.cxx:2: error: static member function 'intt Foo::GetA() const' declared with type qualifiers
と怒られます。

staticメンバ関数ってconstに出来ないんでしょうか。


83 名前:82 mailto:sage [2007/05/13(日) 20:31:18 ]
簡略化して書くときに書き間違えました。
実際には、int aはstaticになっていて、
Foo.cxxの中で定義されてます。



84 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 20:34:34 ]
staticはthisがないという指定なのに、
thisをconstにする指定を併用しても仕方ない

85 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 20:34:35 ]
>src/Foo.cxx:2: error: static member function 'intt Foo::GetA() const' declared with type qualifiers

intt?

セミコロンもないし、単純ミスじゃね?

86 名前:82 mailto:sage [2007/05/13(日) 20:40:11 ]
>>84
あー、なるほど。そういうことですか。

>>85
実際のコードはもっと長いので、
抜き出して書いてます。
inttとか、GetAに()がついてないのとかは、
簡略化したときの打ち間違い。

ってーことは、例えばGetAの中でa++とかやったりとかして、
const関数にしておけばコンパイラが注意してくれるのに、
っていうのは期待できないということですか。

87 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 20:44:51 ]
簡略化するときに何カ所も間違えるようなうっかりさんは、
実際のコードでもミスしてそうだな

88 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 20:48:20 ]
エラーメッセージはコピペだろうから、
intt ってのはリアルで間違ってんじゃね?って思って指摘したんだけどな

89 名前:82 mailto:sage [2007/05/13(日) 21:00:52 ]
本当に申し訳ございませんでした。
皆さん、ありがとうございます。

90 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 21:56:10 ]
すみません。ポインタの素朴な疑問です。
いれこの構造体enemyを固定領域に確保したいときは
struct enemy {
short mainface;
short b;
struct POS Pos[32];
};
struct POS {
short X;
short Y;
};
struct enemy *enemy_struct;
enemy_struct = (enemy*)malloc(sizeof(struct enemy));
でいいんですか?
あとsizeof(struct enemy*)=4ってなるんですけど
struct enemy *enemy_struct;で消費されるenemy型へのポインタの
メモリ領域は4Byteってことですか?

よろしくお願いします。

91 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 22:04:45 ]
>struct enemy *enemy_struct;
>enemy_struct = (enemy*)malloc(sizeof(struct enemy));
>でいいんですか?
だめです。型違いです。

>あとsizeof(struct enemy*)=4ってなるんですけど
struct enemy *enemy_struct;で消費される4byteでおけ



92 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 22:11:23 ]
んんん?問題なくね?

93 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 22:17:37 ]
... = (enemy*)malloc( ...




94 名前:90 mailto:sage [2007/05/13(日) 23:18:34 ]
すんません。型違いということは
..=(struct enemy *)malloc(..
と訂正すればいいんですか?

95 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 01:01:39 ]
>>94
そうだね。それでおk。
実際コンパイルしてみて確認すればいいと思うよ。
入れ子であっても特に使い方に変わりはないよ。
自己参照構造体と呼ばれる特殊な入れ子は慣れるまで厄介(慣れれば便利)
なんだけど、今回はそれじゃないし。
にしても、short変数とか微妙なの使うなあ。

ところでstructが省略できないって事はCを使用しているんだね。
C++では省略が許されたはず。「//」によるコメントみたいに
C++で先に作られてから後になって、ANSIがCの文法として認めたものも
あるから将来は>>90のような書き方も許されるかも。

まあtypedefすれば良いだけなんだけどね。

96 名前:デフォルトの名無しさん [2007/05/14(月) 01:08:45 ]
printf("1¥n");
printf("2¥n");
printf("3¥n");

としたあとに1、2、3を4、5、6と上書きしたいんですが、
CRで先頭に戻るのは分かるのですが(最終行は上書き可能)、
1行前に戻るってのはできるんでしょうか?

97 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 01:18:53 ]
それは処理系依存な方法を使わないとダメ
エスケープシーケンスとか、ConsoleAPIとか

98 名前:96 mailto:sage [2007/05/14(月) 01:26:38 ]
>>97
すいません。環境書き忘れてました。(VT100相当)
エスケープシーケンスでググって、
printf("¥x1b[3A");
で解決しました。
ありがとうございます。


99 名前:デフォルトの名無しさん [2007/05/14(月) 01:52:37 ]
>>90のやり方でもコンパイルは通るんだな。

100 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 12:50:17 ]
asdf<int (int)> a;

みたいな事がしたいんですが、asdfの定義はどういう風にすれば良いかはなんてググれば詳しく出てくるんでしょうか

101 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 12:53:32 ]
boost::function

102 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 12:54:17 ]
なるほど

103 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 13:00:06 ]
asdf<int (*)(int)> a;

のことか?



104 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 13:03:15 ]
なんだと

105 名前:デフォルトの名無しさん [2007/05/14(月) 14:32:49 ]
C言語のあるプログラムで、
Cファイルではなく、hヘッダに
関数を実装している人がいるんですけど
普通なんですか?
やっぱりヘッダに実装する方がベターなんでしょうか?

106 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 14:42:46 ]
はっきり言ってどっちでも良い。
技術的でない話題はマ板へ

107 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 15:00:45 ]
どっちでも良くないよw

ヘッダに実装できるのは内部リンケージの関数だけだけど、
そんなことやっちゃったら同じ関数が複数のソースに定義されて
無駄にも程がある状況になる。

ヘッダに実装する必要があるのはインライン関数だけ。
他は普通はヘッダに実装してはいけない。

108 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 15:11:06 ]
インクルードガードやってたから気づかなかった

109 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 15:16:39 ]
インクルードガードとは関係ない話。
a.h を a.c と b.c でインクルードすれば
a.c と b.c の両方に関数定義が展開される。

110 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 15:17:55 ]
インクルードガードしてりゃそんなけったいなことにはならんだろ。

111 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 15:18:54 ]
と、思ったがなるな。スマン

112 名前:105 [2007/05/14(月) 15:23:06 ]
そうですね。勉強になりました。
ありがとうございました。

113 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 15:48:21 ]
C++ だとテンプレートの実装もヘッダに書く必要がある。
export なんてあってないような仕様だし。

クラスの宣言内に直接関数定義することもあるけど、
これはインライン関数になるから >>107 の範囲内。



114 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 16:55:40 ]
>>a.h を a.c と b.c でインクルードすれば
>>a.c と b.c の両方に関数定義が展開される。
それはへたくそなインクルードガード。
関数の重複インクにならんやり方はちょっと考えれみれ。直ぐわかるやろ。
a.h
 #ifndef …
a.c
 #incliude "a.h"
 …
b.c
 #incliude "a.h"
 …
ただし、それがエエ方法やとは言うてへんど。

115 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 17:06:20 ]
>>114
重複インクルードが問題なのではなく、同じ関数が複数リンクされることが問題。
理解できていないなら、無理にレスしなくていいからね。

116 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 17:38:43 ]
>>重複インクルードが問題なのではなく、同じ関数が複数リンクされることが問題。
>>理解できていないなら、無理にレスしなくていいからね。
だから、「同じ関数が複数リンク]されない方法があるって言うとんじゃ、阿呆かいな。
それとも、ホンマの初心者か?

117 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 17:46:42 ]
そういう方法があるんかしらんが、>>114では何の解決にもなってない。

118 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 17:48:08 ]
>>116
>「同じ関数が複数リンク]されない方法がある
だったらそれを書き給え。

尤も、それならそれで>114の「関数の重複インクにならんやり方」は
一体全体なんなのかという疑問は残るが。

119 名前:≠114 mailto:sage [2007/05/14(月) 17:51:13 ]
>>118
これでOK。
--a.h
#ifdef NEED_FUNC
void func() {}
--a.c
#define NEED_FUNC
#include "a.h"
--b.c
#include "b.h"
--
ただし、これをインクルードガードとは言わないと思う。

120 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 17:53:03 ]
それだとa.cでfuncが使いたいときに困るだろ。

121 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 17:54:27 ]
114のインクファイル中の記述で、ちょっと工夫したら(ヒントは関数の定義じゃ)できると言うとんじゃ。
これだけ言うたら、普通のC言語1年坊主でも気が付くど。気が付かんようなら、C諦めた方がええで。
それより、こんなレベルで初心者を教えるな! 初心者も迷惑じゃ。

>>だったらそれを書き給え。
誰に向かって言うとんじゃ、ボケ。

122 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 17:55:50 ]
すみません、喧嘩しないで頂けますか?

123 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 17:56:24 ]
>>121
分からなくても別に誤魔化さなくていいよ。
俺だって分かんないんだもん。



124 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 17:58:28 ]
まだわからんか?
そもそも”関数名”て何や?

125 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 17:58:51 ]
まさかstaticを付けるというオチでは・・・

126 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 17:59:44 ]
void foo ( ナンたらこたら…
↑で "foo" は何をしとるんや?

127 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:00:37 ]
#define foo
↑で foo は何をされとんねん?


128 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:00:44 ]
>>121
もちろんその方法では、
* a.h に関数の実装を記述する。
* a.c, b.c でインクルードすればどちらからでも使える。
* 関数は重複してリンクされない。
が満たされるんだよな。

129 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:01:33 ]
>>127
焦らさないでくれよ

130 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:01:36 ]
当たり前だのクラッカ


131 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:02:38 ]
もったいぶっちゃって、どうせそんな方法ないんだろ・・・

132 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:05:42 ]
void foo ( なんたらこたら


void bar (ああでもこうでも

#ifndef foo
printf ( "宣言済み" )
#else
printf ( "未宣言" )
#endif


これでもわからんか?


133 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:07:29 ]
void foo ( なんたらこたら

#undef foo
int foo ( ああでもないこでもない

これではどや?




134 名前:≠114 mailto:sage [2007/05/14(月) 18:08:42 ]
staticつけても同じ(内容の)関数が複数リンクされることには違いないしなぁ。
双方のソースから同じ名前で参照される別物の関数と言う条件だと、
どうにもならない気がしてきた。

>>132
まさかとは思うけど、関数を定義したかどうかをディレクティブで
判定できるなんて思っちゃいないよね?
そろそろ正解をどんと出してみてよ。

135 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:08:47 ]
訂正
誤:int foo ( ああでもないこでもない
正:int foo ( ああでもないこうでもない


136 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:09:19 ]
>>133
俺頭悪いからわかんないんだって・・・
意地悪しないで教えてくれよ

137 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:12:58 ]
わかった。リンカディレクティブだッ(w

138 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:15:32 ]
静的メンバ関数として実装するとか?
struct HOGE_unique{
static int hoge() { ... }
};
#define hoge Hoge_unique::hoge

139 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:17:24 ]
もはやCじゃないがな

140 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:19:45 ]
// aaa.h
#ifndef test
int test(int i){return i + 10;}
#endif

// bbb.c
#include "aaa.h"
int test ( int i );
int foo(int i){return test(i)+10;}

// main.c
#include <stdio.h>
#include "aaa.h"
void foo(int i);
int main(void){printf("%d",test(i)+foo(i);}


141 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:23:16 ]
只今>>133は>134を読んで真っ青になっている最中です。
次の御託を思い付くまでもう暫くお待ちください。

142 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:23:51 ]
↑アホ

143 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:30:33 ]
>>137
ttp://sund1.sakura.ne.jp/uploader/source/up5445.mp3



144 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:32:28 ]
>>140
こんなふうにプリプロセスされました。

// main.c
#include <stdio.h>
int test(int i){return i + 10;}
int foo(int i);
int main(void){printf("%d",test(1)+foo(1));}

// bbb.c
int test(int i){return i + 10;}
int test ( int i );
int foo(int i){return test(i)+10;}

145 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:34:23 ]
>>140
testなんかどこで#defineしてるの?

146 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:35:01 ]
test は何回定義されとるん?アセブルリスト見てみ?


147 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:36:30 ]
>>145
宣言されとらんから次のtest()がインクルードされるねんやんかいな。

148 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:39:30 ]
トリッキやよって別々ライブではとおらんけどな。
わしが言いたいのんは「決めつけんな」ちゅうこと。

149 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:40:53 ]
$ gcc -c main.c bbb.c

$ nm main.o
00000000 b .bss
00000000 d .data
00000000 r .rdata
00000000 t .text
U ___main
U __alloca
U _foo
0000000b T _main
U _printf
00000000 T _test

$nm bbb.o
00000000 b .bss
00000000 d .data
00000000 t .text
0000000b T _foo
00000000 T _test

どう見ても両方にtestが含まれてるんだが

150 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:41:22 ]
つまり、関西弁のような発言に見えるからと言って、関西人だと決めつけるな、ということですね?


151 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:42:26 ]
↑そうそう。
それと、gcc はバカやよって別別オブジェ作るねん。

152 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:43:00 ]
なんだ、もう少し笑わせてくれるのかと思ったら意外に伸びなかったな。がっかりだぜ。

153 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:43:09 ]
ようするにはったりだったわけだろ



154 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:44:08 ]
違うやろ、call _test のアドレス見れ

155 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:49:46 ]
char line[] = "abcde¥012345¥0ABCDE";
みたいなことやりたいんですが、
'¥0'があるために、
lineの中身は"abcde¥0"となってしまいます。

当たり前と言えば当たり前なんですが、
回避方法はあるでしょうか。
'¥0'を含む長いchar配列を、
classのstatic constメンバ変数として持たせたいんです。

156 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:50:49 ]
>>155
> lineの中身は"abcde¥0"となってしまいます。
どうやって確認したんだよ。
ちゃんと最後まで入っているはずだ。

157 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 18:51:27 ]
初心者アドバイザは、今、それどころやありません。

158 名前:154 mailto:sage [2007/05/14(月) 18:52:42 ]
「長いchar配列」というのは、数万文字あります。
なので、配列長を確保してから1つずつ代入というのは厳しい。
そんなもん別のテキストファイルにして必要なときに読めよ、
という以外のでお願いします。

159 名前:155 mailto:sage [2007/05/14(月) 19:02:58 ]
#include <iostream>

using namespace std;

int main()
{
char line[] = "abcde¥012345¥0ABCDE";
for(int i=0; i<18; i++){
cout << "(" << line[i] << "," << (int)line[i] << ")";
} // i

return 0;
}

$ ./a.out
(a,97)(b,98)(c,99)(d,100)(e,101)(
,10)(3,51)(4,52)(5,53)(,0)(A,65)(B,66)(C,67)(D,68)(E,69)(,0)(,0)(,0)

となります。

160 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 19:05:13 ]
>>159
コンソールで確認するなよ・・・

161 名前:155 mailto:sage [2007/05/14(月) 19:07:45 ]
> lineの中身は"abcde¥0"となってしまいます。
は不正確でした。すみません。
"12345"の"12"が改行コードLF=10になっています。


162 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 19:08:43 ]
>>159
char line[] = "abcde\0" "12345\0" "ABCDE";
こうしとけ。

163 名前:155 mailto:sage [2007/05/14(月) 19:10:14 ]
>>160
あれ?なんかまずかったですか?
見やすいかと思って。
i=15, 16, 17のときに(,0)となってるので、
ここに何も入ってないんですよね。
なんで"¥012"が"¥0¥n"に化けてしまうのか。



164 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 19:12:28 ]
"\012" が {'\0', '1', '2'} ではなく {'\012'} とみなされてるんだから、
配列の全長が2文字分みじかくなってる。

つまり最後の二つの0は不正なアクセス。

165 名前:155 mailto:sage [2007/05/14(月) 19:12:35 ]
>>162
その方法で、
(a,97)(b,98)(c,99)(d,100)(e,101)(,0)(1,49)(2,50)(3,51)(4,52)(5,53)(,0)(A,65)(B,66)(C,67)(D,68)(E,69)(,0)
になりました。
ありがとうございます。

166 名前:155 mailto:sage [2007/05/14(月) 19:13:53 ]
>>164
ああ、octで解釈されてるわけですか。
なるほど。



167 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 19:24:34 ]
>>159
みたいに
for(int i=0; i<10; i++){
} // i
とか
if(hoge){
} // if
っていう書き方を推奨してる本って、
なんかありませんでしたっけ?
この書き方をどっかで読んだ記憶があるんです。

168 名前:54 mailto:sage [2007/05/14(月) 21:52:47 ]
>>55-58
class A
{
int a;
public:
A(int i) : a(i) {}
A& geta() { return *this; }
virtual void prt() const { printf("a:%d\n", a); }
};
class B : public A
{
int b;
public:
B(int i) : A(0), b(i) {}
virtual void prt() const { printf("b:%d\n", b); }
};
int main()
{
B b(100);
b.geta().prt();
}

これを動かすと「b:100」と表示されて、geta()はA&を戻す筈なのに実際は
B&を戻している訳ですよ。B&を返すメソッドを勝手に定義してくれたほうが
よっぽど自然だと思うんですが、私が愚かしいこと言ってるんですかね?


169 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 22:21:23 ]
うん、けっこう愚かしいと思うよ…。

170 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 22:25:34 ]
>>168が理解できない
どこでB&を戻してるの?

171 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 22:28:25 ]
>>168
class C : public B
{
public:
  A& geta()
  {
    static A a(0);
    return a;
  }
  //コンストラクタほか省略
};
このとき、こうされたらどうする?
C c;
B& b = c;
b.geta().ptr();
B型の式に対してgeta()を呼ぶとB&が返ってくることにしたら、
このb.geta()ではA型のインスタンスへの参照を返しているので型システムを侵すことになる。

だから暗黙的にやらないで、B内ではB&を返すgetaを明示的にオーバーライドしてやったほうがいい。
次のコードはC::getaでコンパイルエラーになる
struct A {virtual A& geta();};
struct B : A {virtual B& geta();};
struct C : B {virtual A& geta();};

172 名前:171 mailto:sage [2007/05/14(月) 22:30:14 ]
すまん
168のgetaも仮想関数だと思い込んでいたorz

173 名前:デフォルトの名無しさん [2007/05/14(月) 22:41:55 ]
とあるソースを読んでいる初心者です.
クラスClass1のヘッダファイル先頭に,下記のように他のクラスClass2,Class3の記述がありました.

#ifndef *******
#include ************
class Class2; class Class3; ←これ

class Class1
public 以下略

これはいったいどういう意味を持つのでしょうか?



174 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 22:57:07 ]
Class2, Class3は別のところでちゃんと定義されてますよ
ってコンパイラに教えるためのおまじない

175 名前:54 mailto:sage [2007/05/14(月) 22:58:24 ]
>>171
なるほど。そのとおりでした。
サンクス。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<189KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef