C++相談室 part61 ..
[2ch|▼Menu]
2:デフォルトの名無しさん
08/03/09 19:38:18
■基本■
[C++ FAQ]
 URLリンク(www.parashift.com)
 URLリンク(www.bohyoh.com) (日本語)
  Cとその仕様を比較しながらの解説なので分かりやすい。
  ***** 質問の前に必ずこの二つに目を通してください *****
[C/C++ リファレンス]
 URLリンク(www.cppreference.com) (英語)
 URLリンク(www.cppll.jp) (↑の日本語訳だけど最新は反映しない)
[禿 Stroustrup]
 URLリンク(public.research.att.com)
[C++ International Standard]
 URLリンク(www.iso.org)
[JTC1/SC22/WG21 - C++]
 URLリンク(www.open-std.org)
  ここから規格の最新(2003より新しい)ドラフトがダウンロードできる。
[JIS X3014]
 URLリンク(www.jisc.go.jp)
  ISO規格の日本語訳。JIS X 3014:2003はISO/IEC 14882:2003 (E)に対応。

3:デフォルトの名無しさん
08/03/09 19:38:41
■Books(Templateまわり)■
Effective STL
 URLリンク(www.amazon.com)
 URLリンク(www.amazon.co.jp) (翻訳)
Modern C++ Design
 URLリンク(www.amazon.com)
 URLリンク(www.amazon.co.jp) (翻訳)
C++ Templates
 URLリンク(www.amazon.com)
C++ Template Metaprogramming
 URLリンク(www.amazon.com)

4:デフォルトの名無しさん
08/03/09 19:39:05
■Libraries■
[Boost]
 Boost URLリンク(www.boost.org)
 (日本語) URLリンク(www.kmonos.net)
 (日本語) URLリンク(shinh.skr.jp)
[標準ライブラリ]
 SGI-STL URLリンク(www.sgi.com)
 STLport URLリンク(stlport.sourceforge.net)
 GNU libstdc++ URLリンク(gcc.gnu.org)
 Apache STDCXX URLリンク(incubator.apache.org)
 STLFilt URLリンク(www.bdsoft.com)
 (日本語) URLリンク(www005.upp.so-net.ne.jp)
 (日本語) URLリンク(www.wakhok.ac.jp)
[Loki]
 URLリンク(sourceforge.net)
 LokiPort-MSVC6sp5 URLリンク(fara.cs.uni-potsdam.de)

5:デフォルトの名無しさん
08/03/09 19:39:25
STLつかうと一気に実行ファイルサイズが10倍に?!

環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない

すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。

C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?

#include <stdafx.h>
後死ね。

言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。

6:デフォルトの名無しさん
08/03/09 19:43:29
前スレ
C++相談室 part60
スレリンク(tech板)

7:デフォルトの名無しさん
08/03/09 19:46:54
>>6
サンクス、連投で制限食らった

8:デフォルトの名無しさん
08/03/09 20:02:21
>>前スレ1000
とりあえず、お前が俺の言っていることを理解出来ていないことだけは分かった

お薦めの本があって、それを教えることには全く反対しないが、
自分で調べたり、情報を探したりしようとしない奴は
大体どうしようもない

一応補足
前スレ984のように聞いてみること自体は別に良いと思う
本を紹介してもらわないと先に進めない、ということでなければ

9:デフォルトの名無しさん
08/03/09 20:05:41
お前のポリシーはどうでもいいよ

10:デフォルトの名無しさん
08/03/09 20:06:48
そういや、こういうヤツがいるから初心者歓迎スレが出来たんだったな

11:デフォルトの名無しさん
08/03/09 20:14:48
ポリシーじゃねぇよ・・・
無能にレスしても無駄のようだな・・・

>>10
初心者に本だけでなく入門サイト探してみたら?って言うのは
アドバイスにならないのか?
自分自身の経験から言っているんだけど
ある程度理解出来てくるとcppllのアーカイブとかも参考になるし

12:デフォルトの名無しさん
08/03/09 20:31:24
おとなしく初心者歓迎スレかオススメ図書スレに誘導してやれよ
今回の様な議論が過去あったからこそそういったスレがあるんだから

13:デフォルトの名無しさん
08/03/09 20:40:52
誘導済みだろ?
俺は別に質問者にレスしてるつもりないし・・・

前スレの985のレスが気に食わない人が居るようなので、
レス返してるだけ

14:デフォルトの名無しさん
08/03/10 00:04:40
>>13
案外質問した人が突っ掛ってたりしてなw
んなわけないか。

15:デフォルトの名無しさん
08/03/10 01:09:34
他スレでis-a、has-aで継承やメンバを考えるみたいな話が合ったんですが、
doはどういう風に処理したらいいでしょうか

アクションゲームとかでAn enemy moves.(敵は動く)とした場合、
moveメソッドはenemyオブジェクトの位置を示すメンバ変数を操作すると思います。
すると、moveはenemyオブジェクトのメンバ関数であるべきと思えるのですが、
他のオブジェクトの位置とかが影響する場合、
enemyオブジェクトをメンバにもつクラス(WorldとかGameとか)に、
全てのオブジェクトを動かすメンバ関数を用意した方が、
他のオブジェクトを参照でき適切に処理できそうです

このような機能を持つメソッドを、皆さんはどの位置に配置していますか?

16:デフォルトの名無しさん
08/03/10 01:17:01
enemyのmoveメソッドはそのままで
WorldやGameからすべてのenemyのmoveメソッドを呼ぶ様にすればいいんじゃね?

ていうかC++関係ないな


17:デフォルトの名無しさん
08/03/10 01:23:43
>>15
もし本当にゲームのことだったら
スレリンク(gamedev板)
とかで聞いた方が良さそう。
それかこの板のクラス設計とかのスレ。

俺だったら、大まかにStrategyパターン的な感じで書くかな。
enemyとかのユニット情報を持った環境(orフィールド)オブジェクトを
参照していじる敵戦略クラス・・・とか。

18:デフォルトの名無しさん
08/03/10 01:31:46
>>16
すみません、自身がCからC++に移行して、
クラス設計に右往左往しているもので、ここで聞いてしまいました

>>17
あ、そんなスレがあったとは知りませんでした

moveメソッドは引数にしたがってオブジェクトの変数を変えるだけ
moveメソッドに渡す引数を敵戦略クラスないし、Worldクラスで決定するって方向で考えて見ます
(moveメソッドの内容が二行で終わりそうだ……。他のメソッドとまとめよう)
ありがとうございました

19:デフォルトの名無しさん
08/03/10 01:34:51
>>18
ちなみに、17のはゲ製板のスレね。

20:デフォルトの名無しさん
08/03/10 01:40:44
飛んできたのはおそらく同じ板のシューティング製作スレだなw

21:17
08/03/10 02:11:11
ターン制で移動先選択→攻撃みたいなの想定してました/(^o^)\
敵戦略クラスは忘れた方が良いw

22:デフォルトの名無しさん
08/03/10 03:05:22
Class().Method();

なんて書けたんだね、、、知らなかったよ(;´Д`)

23:デフォルトの名無しさん
08/03/10 03:20:08
式が何を意味するかによる。Class()がインスタンスなら当然ドットを付けてメンバにアクセスできる。
一通り文法をかじったなら、今度は仕様書を読んでそれを確かなものにした方がいい。流れとしては。

24:デフォルトの名無しさん
08/03/10 22:21:40
ぁぁ、ごめん。はしょりすぎた。

class Class
{
public:
int Method();
};

こんなので、
void F()
{
printf( "%d\n", Class().Method() );
}

な感じ。

25:デフォルトの名無しさん
08/03/10 22:38:15
printf("%d\n", int(5));

な感じ?

26:デフォルトの名無しさん
08/03/10 22:47:08
一時オブジェクトが近々move semanticsな感じ?

27:デフォルトの名無しさん
08/03/10 23:37:58
異なるクラスのオブジェクトをひとつの配列(vector,list)で管理することは出来ないのでしょうか
a[0]はclassA,a[1]はclassB,a[2]はclassC、……という風に
classA、classBは同じpublicなメンバを持っているのですが、
メンバ関数の中身とそこで使うprivateなメンバが異なっています


28:デフォルトの名無しさん
08/03/10 23:49:47
>>27
そういうのこそ、ポリモーフィズムでしょ

29:デフォルトの名無しさん
08/03/10 23:59:11
>>28
関数の多重定義のことでしょうか

ClassAとClassBの異なるメンバもひとつのクラスにまとめて、
使わないメンバがあっても気にしない、という方針でもいいんですが、
無駄にメモリを消費するのがイヤなもので

30:デフォルトの名無しさん
08/03/11 00:01:24
全く関連のないクラスを1つの配列に入れるという時点でかなりおかしいと思う。
関連というか共通項があるからこそ1つの配列に入れるんだろう?

31:デフォルトの名無しさん
08/03/11 00:06:44
>>29
仮想関数ってやつだ。
class Base {
public:
virtual ~Base() {}
virtual void func() = 0; // 共通のメンバ関数
};
class A : public Base {
public: virtual void func() { /* classAの処理 */ }
private: /* classAのメンバ変数 */
};
class B : public Base {
public: virtual void func() { /* classBの処理 */ }
private: /* classBのメンバ変数 */
};
このようにしておいて、たとえば
Base* p1 = new A;
Base* p2 = new B;
とすれば、
p1->func(); // A::funcが呼ばれる
p2->func(); // B::funcが呼ばれる
となる。
あとはvector<Base*>にすれば万事解決では。

32:デフォルトの名無しさん
08/03/11 00:09:10
boost::ptr_vector だと勝手に delete してくれるから楽だよ。

33:デフォルトの名無しさん
08/03/11 00:43:37
>>30
アクションゲームで
A:単純な移動しかせず体当たりでダメージを生む敵
B:主人公の位置などを頼りに複雑なアルゴリズムで動き多彩な攻撃をする敵
こんな感じでAの方が圧倒的に必要なメンバ変数が少なく、
かつAの方が数が多いので、Bに合わせてメンバ関数を増やすとメモリを食らってしまうのです

>>31
>Base* p1 = new A;
AがBaseを継承していると、こんな代入も可能なのですか……
ありがとうございました

>>32
ググってみましたが、new演算子を使いまくるなら、便利そうですね
仕様に慣れるよう練習してみます

あちがとうございました

34:デフォルトの名無しさん
08/03/11 00:44:13
誤字修正
×Bに合わせてメンバ関数を
○Bに合わせてメンバ変数を

35:デフォルトの名無しさん
08/03/11 02:31:06
>>33
とりあえず
継承、多態(ポリモーフィズム)、オーバーライド
等を調べるんだ

AとBの共通する部分を基本クラス(やinterface)としてくくりだせ

36:デフォルトの名無しさん
08/03/11 11:10:02
エピステーメー氏の「C++言語のカラクリ」の話題出た?
なめて読んでたら「自己記述の必然性」が全く理解できない。
どうにか「だから単純なC++→C」のコンバーターじゃ駄目なんだよって
一言で説明できないか?

37:デフォルトの名無しさん
08/03/11 11:49:30
C++をC++で記述できないとだめだということ?
何だかよく分からないな。でもあの人はたまに哲学よりのトンデモを平気で書いたりするから気にしちゃいけないよ。

38:デフォルトの名無しさん
08/03/11 12:02:24
Cだけではtrr..catch..throwが実現できなかったって話だろ。
でも話題が古いなあ。

39:デフォルトの名無しさん
08/03/11 12:23:12
自己記述できることが○○だ(スバラシイとか完備だとか)
って誰かに刷り込まれたんかな

頭悪いな

40:デフォルトの名無しさん
08/03/11 12:26:33
コードジェネレータ通すとデバッグがやりにくそう

41:デフォルトの名無しさん
08/03/12 00:28:22
VMのスタック上で記号処理を介せば
殆どの言語は自己記述可能だが

と書けばミもフタもないのか

42:デフォルトの名無しさん
08/03/12 02:44:49
IO機能がないんですがどうすればいいですか。

43:デフォルトの名無しさん
08/03/12 05:26:59
URLリンク(www.google.com)

44:デフォルトの名無しさん
08/03/12 05:33:36
42は41へのレスなんじゃなかろうか

45:デフォルトの名無しさん
08/03/12 05:48:23
orz

46:デフォルトの名無しさん
08/03/12 10:24:06
自己記述ってどんなの?

47:デフォルトの名無しさん
08/03/12 11:16:52
ある言語やその処理系でその言語を実行できる処理系を書くことだお

48:デフォルトの名無しさん
08/03/12 13:28:47
多分要はメタプログラミングは必要だから出てきたんだ、偶然や酔狂じゃない。
ってことを言いたいんだろ?読んでないけど。

49:デフォルトの名無しさん
08/03/12 21:59:43
あれ?なんかtemplateで遊んでたらメタプログラミングできちゃったぞ

って感じ

50:デフォルトの名無しさん
08/03/12 22:01:01
typedef std::map<size_t,Dummy> DummyMap;
DummyMap dmap;
....

DummyMap::iterator it = dmap.find(index);
Dummy& dummy = (it != dmap.end()) ? it->second : dmap[index];

っていうこと(イメージ)をしたいんだが、\
findして、insertすると少なくとも2回の走査が行われていて、無駄な感じがする。
どうすべきか、アドバイスをくだされ。

51:デフォルトの名無しさん
08/03/12 22:02:34
趣旨を間違った。
これじゃ普通にdmap[index]すればいいじゃねーか。

出直してくる。

52:デフォルトの名無しさん
08/03/12 22:41:37
韓国人宇宙飛行士が国際宇宙ステーションに搭乗する際の活動に関する日本韓国間の協力について
URLリンク(www.enjoykorea.jp)

日本の大事な税金で作ったものを何で韓国人にタダでつかわせるんだ!
苦情メールを送ろう!
JAXA     URLリンク(www.jaxa.jp)
文部科学省  URLリンク(www.mext.go.jp) 
御意見・お問い合わせ専用メールアドレス voice_atmark_mext.go.jp

全く他人事じゃないんですけど>ロシア

宇宙ステーションをただで使わせて写真とらせるとかいってますが・・
抗議してくれ。

朝鮮人どもまじで死んでくれ。

53:デフォルトの名無しさん
08/03/12 23:42:33
>>51
定型はこう、かな

iterator it = map.lower_bound(key);
if(it == map.end() || it->first != key) {
it = map.insert(it, Dummy());
}
Dummy &d = it->second;

54:デフォルトの名無しさん
08/03/13 00:02:54
> it->first != key
これは問題なければ良いんだけど、正確にはlessを使えとかそういう話、無かったっけ?


55:デフォルトの名無しさん
08/03/13 00:24:47
it->first != key
lower_boundの戻り値はpairじゃないよな。確かキーだよな。

ソート基準がデフォのlessならこうか。

if(it != map.end() || !(key < *it)) {
//found
} else {
//not found
}

56:デフォルトの名無しさん
08/03/13 00:26:26
||じゃなくて&&だわ

if(it != map.end() && !(key < *it)) {
//found
} else {
//not found
}



57:デフォルトの名無しさん
08/03/13 00:37:32
>>55
lower_bound()の戻り値はpairだよ。
・・・というより、map<k, v>::value_typeがpair<k, v>だ、と説明するほうが、根本的で適切かな。
std::コンテナ::iteiratorは、std::コンテナ::value_typeのポインタ的に動作するわけだから。

>>53-54
「厳密には」こう書くべき。
if (it == map.end() || map.key_comp()(key, it->first) {

58:デフォルトの名無しさん
08/03/13 00:38:36
ごめん訂正。
- map<k, v>::value_typeがpair<k, v>
+ map<k, v>::value_typeがpair<const k, v>

59:デフォルトの名無しさん
08/03/13 00:46:26
>>57
ああ、そうだね。elementの型がpairだた。スマソ。

60:デフォルトの名無しさん
08/03/16 05:51:19
テスト

61:デフォルトの名無しさん
08/03/16 05:55:48
class B;

class A
{
B b;
};

class B
{
A a;
};

と書いたところ、
エラー出ます><。
どう対処すればいいですか?


62:デフォルトの名無しさん
08/03/16 06:04:28
よく考えようぜ。
A の中に B がある。
その B の中に A がある。
その A の中に B が・・・

あり得ない。


とりあえず何をしたいのか整理しよう。
大抵の場合は、

1. クラス設計を変更する。
2. a と b のどちらかを参照にする。

のどちらかになる。

63:デフォルトの名無しさん
08/03/16 06:31:59
haskellを使う

64:デフォルトの名無しさん
08/03/16 07:41:30
>>61
Aの中に持ちたいのはBそのものじゃなくて、Bの参照なんじゃね?

65:デフォルトの名無しさん
08/03/16 15:02:01
>>62
循環して持ちたいのはよくあること。
やるなら>>64のようにすればいい。

同じような質問見つけてきたんで参考にどうぞ。
URLリンク(www.atmarkit.co.jp)

66:デフォルトの名無しさん
08/03/16 15:45:33
62にそう書いてるじゃん

67:デフォルトの名無しさん
08/03/17 03:49:28
くだらない質問で申し訳ないのだけど、どなたか教えてください
クラスのコンストラクタで関数名の後ろにつけている初期化みたいなものの意味を教えてください

hoge::test() : a(0),b(0),c(0)
{
...
}

この場合だとa=0,b=0,c=0?
だとしたらなぜ...のところに書かないのですか?

68:デフォルトの名無しさん
08/03/17 04:07:50
test

69:デフォルトの名無しさん
08/03/17 04:11:10
test()じゃエラー出ると思う

hoge::hoge() : a(0),b(0),c(0)
{
...
}
のことだよね
aが変数だと問題ない?けど

aがクラスの場合、aのコンストラクタに0という引数渡すということ。

class a{
public:
a(int value);
};
みたいなクラスの場合、aのコンストラクタに数値渡さないと作成できないし

70:デフォルトの名無しさん
08/03/17 04:29:44
変数とクラス名が同じだとエラー出るや

class A{
public:
A(int value);
};

class hoge
{
A a;
public:
hoge() : a(0)
{
...
}
};
ってこと
この場合
...の所に a = 0; って書けない

71:デフォルトの名無しさん
08/03/17 08:54:36
>>67
前者は初期化で、後者は何らかの初期化、または未初期化で構築の後、代入だな。
どちらでも良い場合はあるけど、意味は明確に違う。

例えばconstが絡んだ場合とか、

class hoge{
const int a; //constなので代入できない。
};

>>69のようにメンバの構築に引数が必要な場合とか。

未初期化な変数を嫌ったり、デフォルトコンストラクタの後に代入するような
効率の悪さを嫌ったり、色々あるからできるだけ初期化を使う。


72:デフォルトの名無しさん
08/03/17 10:11:47
CとC++の違いを徹底解説!みたいな本に
Class::Method():field(0),field1(0)
{
}
なんて書いてあってさ、
何だよコンパイラバグってんじゃねーか!とか思ったころがあった

73:デフォルトの名無しさん
08/03/17 10:39:23
>>72 本の名前晒しといてくれ。

74:デフォルトの名無しさん
08/03/17 10:40:42
ていうかさ、constメンバや参照メンバもそうだけど
基底クラスの初期化も、この形式じゃないと出来ないよ。

もちろん、引数なしのデフォルトコンストラクタでの初期化は可能だけど。

75:72
08/03/17 11:55:05
「オブジェクト指向言語C++入門 Cとの違いを徹底追求」
これかな。
やっぱり古いのもあってか、<string.h>とか、
namespace、例外の話はまったくなかった。
それ意外と、多少の誤植を除けば、解り安くもなければ解りづらくもない中立的な本だった。

まぁ、今となっては読むべき本じゃないわな

76:デフォルトの名無しさん
08/03/17 13:02:50
低レベルな質問は初心者スレでやれ

77:デフォルトの名無しさん
08/03/17 15:16:38
>>76
おまえが、↓に行け

C++上級者が集まるスレ
スレリンク(tech板)


78:デフォルトの名無しさん
08/03/17 16:49:26
関数の戻り先アドレスがバッファオーバーランで壊されているようなんですが、どこで壊されているのかが分かりません。

a(){

b();

}

b(){

// ログに戻り先アドレスを記録

/* 処理1 */

// ログに戻り先アドレスを記録

/* 処理2 */

// ログに戻り先アドレスを記録

return;
}

あたりをつけるために、上のように処理の区切りで関数の戻り先アドレスをログにはき出そうと思うんですが、
戻り先アドレスをどのように参照していいかが分かりません。

もし分かりましたら、参照方法を教えてください。
よろしくお願いします。

79:デフォルトの名無しさん
08/03/17 17:02:46
環境に依存します

80:デフォルトの名無しさん
08/03/17 17:17:10
>>78
そこまで推測できているならデバッガでスタックにトリガ張ればすぐだろうし、
そうでなくてもコンパイラにスタックのチェックをするオプションがあったりしないか?
そもそもバッファオーバフローだと判っているなら関数内のポインタを全部洗えばいいだけじゃん。
# 巨大関数だったらしらねw

81:デフォルトの名無しさん
08/03/17 17:27:32
>>79
失礼しました。
Windows2000 VC++6です。

>>80
それが、1ヶ月に1度位しか発生しないエラーなのでトレースが困難なんです。
各所にログを埋め込み、関数から戻ってこないのは確認できたので、戻り先アドレスが壊されているらしいと推測したんです。
次はどこで壊されるかをログに記録し、また1ヶ月待ってみようと思いましてw

82:デフォルトの名無しさん
08/03/17 17:30:16
espでも記録しておくとか

83:デフォルトの名無しさん
08/03/17 17:46:56
>>81
>79の時点でスレ違いだと気付こう。
>そうでなくてもコンパイラにスタックのチェックをするオプションがあったりしないか?

84:デフォルトの名無しさん
08/03/17 18:21:17
>>83
申し訳ありませんでした。
色々なアドバイスありがとうございました。

85:デフォルトの名無しさん
08/03/17 21:45:50
const T &なメンバをもつクラスを作ったんだが、
ひょっとして、コピーする手段がない?

86:デフォルトの名無しさん
08/03/17 21:51:54
クラス初期化にしかconst T &は初期化できないから
まぁなんというか頑張れ

87:デフォルトの名無しさん
08/03/17 22:03:17
コピーコンストラクタならおkだが、operator=はダメだろうな

88:デフォルトの名無しさん
08/03/17 22:47:28
const_ca

89:デフォルトの名無しさん
08/03/18 00:27:05
なんで&があるん?
*だけじゃ駄目なん?

90:デフォルトの名無しさん
08/03/18 01:01:24
駄目です

91:デフォルトの名無しさん
08/03/18 01:23:09
なんで

92:デフォルトの名無しさん
08/03/18 01:24:56
インラインアセンブラ使えばコピーできないことはないだろうが
当然おすすめはしない。

93:デフォルトの名無しさん
08/03/18 01:32:09
関数gがコンパイルエラーになります。なぜですか?不可解です。

class X {
protected:
  int val;
};

class Y : public X {
public:
  void f(Y* p) { p->val = 0; } // OK
  void g(X* p) { p->val = 0; } // エラー
};

94:デフォルトの名無しさん
08/03/18 01:53:29
X::valはYから見ればprivate
Y::X::valはYから見ればpublic

95:デフォルトの名無しさん
08/03/18 01:55:26
あ、いや、privateというべきじゃなくprotectedでいいのかな。どっちだろ。
いずれにせよYからX::valは触れない。Y::X::valなら触れる。

96:93
08/03/18 02:05:40
>>95
やっぱりそうですか。なんとなく奇妙な言語仕様に思えるのですが。。。

97:デフォルトの名無しさん
08/03/18 02:21:17
じゃなぜこういう風に難解なルールになっているか逆に考えてみればわかる。

class Y2 : public X {
 void f(Y* p) { p->val = 0; }
};

というXを継承した別のクラスを作ってみよう。YとY2は別のクラスなのでY2から
Yのprotected属性のメンバ変数が変更出来てはまずいのに、もしこのような
ルールがなかったら上の例で可能になってしまう。

モジュールの隠蔽が破られないように特別なルールが作られているわけだ。

98:93
08/03/18 02:33:25
なるほど。なんとなくですが、分かりました。

99:デフォルトの名無しさん
08/03/18 07:13:26
fseekgでstr.length()分を戻したいのですけど、
単にマイナスをつけて、-str.length()とするとイミフな数値しか出ません。
何でうまくいかないんでしょうか?

100:デフォルトの名無しさん
08/03/18 07:39:13
事故解決しました。 length()が返すのはsize_typeで、
size_typeはsize_tのunsigned intみたいだからですね。

101:デフォルトの名無しさん
08/03/18 20:26:40
出しかたによる。

102:デフォルトの名無しさん
08/03/18 20:37:42
>>100
環境依存の話すんなくそったれ

103:デフォルトの名無しさん
08/03/18 22:02:40
この言語機能多すぎじゃね?

104:デフォルトの名無しさん
08/03/18 22:14:29
必要な部分だけ使え

105:デフォルトの名無しさん
08/03/18 22:23:31
>>102
少なくともsize_typeは符号無しということは標準で決まっている事柄だったと思う。

106:デフォルトの名無しさん
08/03/18 23:49:31
>>105
unsigned intとどこに書いてある?

107:デフォルトの名無しさん
08/03/19 00:00:40
お前は何を言ってるの?

108:デフォルトの名無しさん
08/03/19 00:22:24
>>106
それは規格のどこにも書いていないが、
例えばもし99=100が使っている実装のsize_typeが
仮にunsigned longやunsigned shortだったとしても、
99=100は同じように質問して同じように解決していたに違いない。

たまたま100の使っている実装でsize_typeがunsigned intだったこと以外は
標準C++で普遍的に成り立つ話じゃないか。

109:デフォルトの名無しさん
08/03/19 00:24:39
size_typeは符号なし整数。
ただしbit数は決まってない。

110:デフォルトの名無しさん
08/03/19 06:33:43
>>108
頭の悪い子って、「話の行きがかりで登場したディテール」と「そのディテールに依存した話」の違いが
わからないから困るよね。

少なくとも、「環境依存の話すんなくそったれ」と「unsigned intとどこに書いてある?」の2レスより、
「でも規格で決まってるのはunsignedってことだけだから注意」とか書くほうが簡潔で有用。
非・馬鹿は最初からこう書く。

111:デフォルトの名無しさん
08/03/19 07:24:46
size_t が unsigned long のこともよくあるしな。

112:デフォルトの名無しさん
08/03/19 09:04:06
unsigned short だったりすると -length() しても int 型で普通に負の数になったりして。

113:デフォルトの名無しさん
08/03/19 12:28:38
std::cinで文字や数値を入力するとバッファに改行文字が残るようで、
その後に std::getline(std::cin, buf, '\n'); とかやらせると残った改行文字だけ読み込んでしまいます。
バッファをクリアする方法がないかと調べてみたのですが、
環境に依存せず確実にクリアする方法はない、という記述がありました。

こういう場合はそもそもstd::cinを使わないようにするのがよいのでしょうか?
fgetsとかを代わりに使えば改行文字まで読み込んでくれるみたいなのですが、
std::cinの方がすっきりしたコードになるので、他に問題を回避する方法がないか探しています。

114:デフォルトの名無しさん
08/03/19 12:45:02
>>113
cin.ignoreを呼ぶとかcin.getを繰り返すとかで十分では?

115:デフォルトの名無しさん
08/03/19 12:49:09
ああ、なるほど。
この場合はバッファに残るのが改行文字一個だけと分かってるから、それで十分なんですね。
ありがとうございました。

116:デフォルトの名無しさん
08/03/19 15:15:14
cinから一行読み込み+istringstreamで良くね?
string line;
getline(cin,line);
stringstream linestream(line);

117:デフォルトの名無しさん
08/03/20 15:40:59
#define Max 1000

みたいなのを、グローバル変数を使って

const int Max = 1000;

とした方が良い(型指定ができるから)、と読んでる本で出てきました。
色んな所で「グローバル変数はできるだけ使うな」と言われていたのでびっくりしてしまったのですが、
こうやってconstにして#defineの代わりにするのは例外的によく使われるものなのでしょうか?

118:デフォルトの名無しさん
08/03/20 15:46:50
defineよりはマシってだけの話。

119:デフォルトの名無しさん
08/03/20 15:52:08
グローバル変数の議論とはまた別の話しだろ

120:デフォルトの名無しさん
08/03/20 15:56:36
>>117
グローバル変数がダメなだってだけ覚えてて、なぜダメなのか考えたこと無いみたいだね?
大雑把に言うとどこで変更してるか分からないから把握しづらいといったとこです

const つけた場合(やろうと思えばできるけれど)変更できないので、そういう害は無い

121:デフォルトの名無しさん
08/03/20 15:58:48
あほすぎるw

122:デフォルトの名無しさん
08/03/20 16:53:57
別の翻訳単位で参照する可能性のある“変数”ならグローバル変数を使う。
別の翻訳単位で参照する可能性のある“数値”なら#define定義のあるヘッダを各自インクルードすればいい。

123:デフォルトの名無しさん
08/03/20 17:11:37
>>122
なに言ってんの?w

124:デフォルトの名無しさん
08/03/20 17:12:31
const ついてるやつはグローバル定数と呼ぶべきもの。

125:デフォルトの名無しさん
08/03/20 17:17:00
>>117
グローバル変数に限らず、「○○はよくない」などと言われる物は絶対にダメという意味ではない。
○○以外の有効な手段があればそれを選べという意味であって、○○が有効となる限られたケースでは使っていい。

126:デフォルトの名無しさん
08/03/20 17:18:31
理由を理解せずに規約に従っても意味がない事の典型だな

127:デフォルトの名無しさん
08/03/20 18:31:27
>117
基本的にマクロは(特定の使い方以外)使わない方がいい。
マクロはプリプロセスで処理されてしまうため、コンパイルエラー時に酷い目に会う。
グローバル変数も使い方が難しいけど、コンパイラが識別できるものなのでマクロより余っ程マシ。
エラーが発生してもあくまで“変数”なので、マクロと違って識別名が普通に表示されるので
トレースしやすい。

因みに言うと、グローバル変数にするかどうかは「その値がどの範囲まで影響するか/正しいか」というのを
考えて決めるべき。プログラム中で一意な定数は積極的にconstグローバル変数にすべきだわな。

……しかし、こういう「疑問点を自ら追求する力を付ける」のがゆとり教育だったはずなんだけどね。
やっぱり失敗だったのか……

128:デフォルトの名無しさん
08/03/20 18:37:15
なんで勝手に117をゆとり教育を受けた人認定してるんだよ

129:デフォルトの名無しさん
08/03/20 18:41:28
エスパーするとC++でなく、Cの人が居ます。
「const リンケージ」でググって下さい。

>>117
C++で、それはただの定数で
変数のように書き換えることは出来ません。

グローバル変数が嫌われる主な理由は、
どこで書き換えられるか、把握し辛いことにあるため、
定数には当てはまりません。

130:デフォルトの名無しさん
08/03/20 18:56:40
どう見てもゆとりです、本当にありがとうございました。

131:デフォルトの名無しさん
08/03/20 20:02:06
1. マクロ定数はアドレスを完全に持たない。
 (const 定数はアドレスを取得しようと思えばできるが、
  アドレスを取得しさえしなければデータがデータメモリ上に置かれるとは限らない)

2. const 定数は名前空間に所属できる。
 (マクロには名前空間がないため、名前被りが発生する可能性が大きい)

3. 値を求めるのに何らかの処理を伴う定数を使う場合、マクロだと毎回コードが埋め込まれてしまう。
 (最適化が効く範囲ならいいのだが)

4. const 定数の方がコンパイルエラーが読みやすい。
 (マクロの場合、置換後のテキストを元にしてエラーが出力されてしまう)

5. マクロの場合、型を明確に指定するには明示的なキャストが必要になる場合がある。
 (見た目の問題でしかないと言われればそれまでだが)

6. ローカルスコープ内であっても、マクロ定数と同名の識別子を作ることはできない。
 (作れない方がいいという意見もあるのかもしれないが)

7. const 定数を使うと副作用が一切無いことが明示される。
 (キャスト演算子をオーバーロードしているクラスのオブジェクトの場合は例外だが)

132:デフォルトの名無しさん
08/03/21 11:21:21
質問があります。

動的配列を解放するときは要素数とかバイト数を指定しなくても

delete [] p;

でokですが、これはポインタpが指している動的配列の先頭バイトの
前に4byteの領域が確保されていて、ここに動的配列のバイトサイズ
が格納されているから、delete時にサイズを指定する必要がないと
聞いたことがあります。

しかし、動的配列の総バイト数はわかるとしても、要素のバイト数
の情報はどこに格納されているのでしょうか?

int *p; なら1要素のバイト数は4、double *p; なら1要素のバイト数は
8ですが、実行時にこの情報はどこから取得するのでしょうか?

ポインタpそのものは先頭1バイトのアドレス情報しか保持して
ませんから、こういう疑問をもった次第です。

133:デフォルトの名無しさん
08/03/21 11:30:24
ポインタそのものにそのアドレスに何が格納されてるかの情報は含まれてる。
そうでなければ cout << *p << endl; とかやったときに何が表示されるか未定義になってしまうじゃないか。

134:デフォルトの名無しさん
08/03/21 12:15:53
>ポインタそのものにそのアドレスに何が格納されてるかの情報は含まれてる。

ありがとうございます。

ポインタは、単に先頭バイトのアドレスを格納する4バイトの記憶
場所をもっているだけでなく、動的データ(または動的配列の要素)
のバイト数とか、データが文字なのか、整数なのか、実数なのか、
といった情報も裏側にもっている。これらの情報はポインタが指す
動的変数や動的配列側にではなく、ポインタ側にある。

という理解でよろしいでしょうか?

135:デフォルトの名無しさん
08/03/21 12:21:02
>>134
違う。ポインタの型によって静的に決まる

136:デフォルトの名無しさん
08/03/21 12:21:50
静的に型付けされてるからそんなものは要らない。

137:デフォルトの名無しさん
08/03/21 12:23:04
まさかvoid*をdeleteしてないよな…
あとポインタが4バイトとは限らないぞ。

138:デフォルトの名無しさん
08/03/21 12:30:09
うーん、わからなくなってきました。

文字型変数、整数型変数、実数型変数がコンパイル時に静的に
型付けされているのと同じというのは概念的にわかります。

しかし、自分が質問しているのは、その静的な型付けをどのよう
なしくみで実装しているのか?ということだろうと思います。

この段階にくると、コンパイラやアセンブラが理解できないと
無理なんでしょうけど。

139:デフォルトの名無しさん
08/03/21 12:50:07
実行時に要素のバイト数は、どこにも格納されてない。
と、考えて良い。

コンパイルする時点では、当然型が分かるので、それを使う。
この段階というか、かなり基礎。

※RTTIは上記が理解出来た上で。

140:デフォルトの名無しさん
08/03/21 12:59:28
>>138
いっぺん、自作クラスにoperator newとoperator deleteを実装してみればいいんじゃないかな。

乱暴な説明だけど、C++には「確保/削除するバイト数を受け取る、new/delete一族の大ボス的存在」である
::operator new(size_t)と::operator delete(void*, size_t)があって(他にも多重定義があるけど、とりあえず今はこの2例)、
たとえば int* p = new int; なんてのは、int* p = ::operator new(sizeof(int)); みたいにコンパイル時に解釈される。
同じく、後にdelete p; が出てきたら、pがint型のポインタなのはコンパイラにはわかるから(てか俺等にだってわかる)、
こっちは ::operator delete(p, sizeof(int)); になる。

141:デフォルトの名無しさん
08/03/21 13:24:09
>>138

>int* p = new int; なんてのは、int* p = ::operator new(sizeof(int));

int *p= new int [100]; は int *p=::operator new(sizeof(int)*100);
みたいになるんでしょうけど、要素のサイズが2バイトなのか4バイト
なのかの情報をコンパイル時にポインタに付加しておかないと、p[i]の
アクセスがうまくいかないのではないかと思うのですが、どうでしょうか?



142:デフォルトの名無しさん
08/03/21 13:25:59
>>141
p[i]のpの型はコンパイル時に分かってるんだから

143:デフォルトの名無しさん
08/03/21 13:44:43
まあ、強いて言えば、生成されたコード内に埋め込まれているって感じなのかな。

delete[] p;するときに、各要素のデストラクタを起動しなければならないわけだけど、
要素数は p = new T[count]; のcountで、実行時に変わる可能性のあるものだから、
ポインタの前かなんかに隠しておかなければならないわけ。
ちなみに、メモリブロックを単純に解放するだけなら要素数を隠しておく必要はないよ。
free()にサイズを指定しないでしょ?
メモリマネージャはメモリブロックの総バイト数をどこかに隠しておくかもしれないけど、それは別の話。

あとは、
T *p;
for(size_t i = 0; i < count; i++){
p->destruct();
++p; //←これ
}

これの++pがどうコンパイルされるかという、>>139が言うようにC言語レベルの基本的な話。


144:デフォルトの名無しさん
08/03/21 13:56:21
>>141
> p[i]のアクセス
たとえばintが4byteの環境だとすると、p[i] と書かれた箇所はネイティブコードにおいては
「pのアドレス+i*4byteのメモリアドレスへ行ってそこから先4byte分に書き込まれているビット配列を〜」
という風に、既にintが「4byte」というミもフタも無い表現に変わっているから、型情報も何も関係無いよ。

145:デフォルトの名無しさん
08/03/21 14:27:51
>>141
p[i]というコードはコンパイルすると、アドレスはp+4*iといった意味の命令が生成される。
4が出てくる理由はpの宣言int* pによるもの(intが4byteの環境の場合)。

146:145
08/03/21 14:36:28
すまん、144と同じ事書いてしまった。

147:141
08/03/21 17:03:54
返事が遅くなってすみません。みなさん、ありがとうございます。

>>144 さんと >>145 さんの説明で

4byteという要素バイト数の情報をポインタp自体が保持して
いるのではなく、p[i]にアクセスする際にコンパイラがp+4*i
を計算する命令を生成しているだけ、ということがやっと理解
できました。

148:デフォルトの名無しさん
08/03/21 18:35:45
配列 new の場合、アップキャストは行わないから
配列のサイズは型から静的に決まる、と。
というか、アップキャストはできない。
そこが鍵だな。

149:デフォルトの名無しさん
08/03/21 18:36:13
×配列のサイズ
○要素のサイズ

150:デフォルトの名無しさん
08/03/21 18:44:36
C++ 的にはフォーマットの決まった string の中から数字を
読み出したりするにはどうするのがお薦めなのでしょうか?
例えば

string s("# foo 30 bar 0.1 xlajkdfl;ajkds");

から 30, 0.1 を抜く場合。

int n;
double x;
sscanf(s.c_str(),"# foo %d bar %lf",&n,&x);

としたりするのですが、もっと「本来」の方法はあるのでしょうか?
どうも workaround 的な気がするので。



151:デフォルトの名無しさん
08/03/21 18:48:30
atofで一つずつ進めて数値になる所を取り出す

152:デフォルトの名無しさん
08/03/21 18:51:36
それはないな

153:デフォルトの名無しさん
08/03/21 19:53:08
自分で字句解析器を書く。

154:デフォルトの名無しさん
08/03/21 20:00:28
各種正規表現ライブラリの後方参照を使う

155:デフォルトの名無しさん
08/03/21 20:29:16
>>150
そういうのが必要になる状況ってあまり無くない?

156:デフォルトの名無しさん
08/03/21 21:08:24
>>155
俺はソースコード解析したい時によくでる。
字句解析ライブラリもってこいって話だよな・・・

157:デフォルトの名無しさん
08/03/21 21:51:06
字句解析なら分かるんだけど、>>150は何か違う気がしたんで・・・
そうなら、分割の話から入るだろうし。

もしかして自然言語文からの抽出とかかな?

158:150
08/03/21 23:35:25
皆様どうもありがとうございました。私は結構こういう必要に出会います。
主にデータファイルをフォーマットし直したり、それを処理する場合です。
例えばデータフォーマットの情報などた先頭にあったりして、その情報を
元に解析したりする場合です。無視して決め打ちする事も可能な場合も多い
ですが、安全性のために整合性をチェックしています。

>>154 さんの方法が私には合っていると思います。普段 Ruby とかも使って
いて正規表現も使っているのに惰性で C 的にを使い続けてる自分の頭の堅さ
には呆れました。基本的に以下のようなコードで対応することを考えています。

まだあまり考えていないのでもう少しエレガントに書けるだろうとは思います。

string s("# foo 30 bar 0.1 xlajkdfl;ajkds");
boost::regex r0("^# foo ([0-9.]+) bar ([0-9.]+).+");
boost::match_results<std::string::const_iterator> mr;
if(boost::regex_match(s,mr,r0)){
const int n = boost::lexical_cast<int>(mr.str(1));
const double x = boost::lexical_cast<double>(mr.str(2));
cout << n<<"\t"<<x<<endl;
}



159:デフォルトの名無しさん
08/03/22 00:19:27
>主にデータファイルをフォーマットし直したり
それまさに字句解析の範疇な気がするけど・・・w

まぁ正規表現で簡単に済めばそれで良いと思うけどね。

160:デフォルトの名無しさん
08/03/22 12:44:30
>>159
> まぁ正規表現で簡単に済めばそれで良いと思うけどね。

regex ってかなり強力だと思う。テキストから情報拾う場合
に regex では簡単に通用しない場合ってどういうケース?

161:デフォルトの名無しさん
08/03/22 13:14:39
>>160
ネストした括弧の対応を取るとか

162:デフォルトの名無しさん
08/03/22 14:07:16
そこでboost::xpressiveですよ

163:デフォルトの名無しさん
08/03/22 14:15:50
boost もいろいろあってわからんなぁ。xpressive だと簡単なのかな。

俺だと char ごと読み取って '(' ')' を +1, -1 でカウントするとか
低レベルな事を考えちゃうけど。

164:デフォルトの名無しさん
08/03/22 14:52:00
 通常の正規表現では任意のネストを表現することができない。
→xpressive ではパターンの自己再帰記述が可能。
→正規表現の枠を超える表現力を持つ(文脈自由文法)。
→xpressive だとネストの対応が可能。

165:デフォルトの名無しさん
08/03/22 15:01:28
boostの文字列処理ライブラリの事ならboost本のサンプルで読めたな

166:デフォルトの名無しさん
08/03/22 15:21:10
boost 本でお薦めってある? 本あまり出てないよね。

Karlsson の本は目を通したけど感じは判ってよいけど便利な本
という感じではない。秀和から出てる稲葉さんは本厚いし内容あるのかな。


167:デフォルトの名無しさん
08/03/22 17:31:22
inabaさんのは導入+軽いリファレンスにはいいかも
おおまかな概念と使用例が載ってる
boostもう使ってるよ〜という人にはあまり必要ないかも


168:デフォルトの名無しさん
08/03/22 17:31:23
複数の派生クラスがそれぞれ値の異なるconst staticなメンバ変数をもっていて、
基底クラスへのポインタを使って読み取りたいのですが、どうすればいいでしょう
基底クラスへのポインタの配列に、いろいろな派生クラスを突っ込んでいる状態なので、
直接アクセスすることは出来ません


169:デフォルトの名無しさん
08/03/22 17:49:42
URLリンク(www.s-cradle.com)

170:デフォルトの名無しさん
08/03/22 17:54:12
>>166
C++ Template Metaprogramming

171:デフォルトの名無しさん
08/03/22 17:56:20
>>168
普通に仮想関数で
struct Base { virtual StaticMemberType GetStaticMember()=0; };
struct DerivedA : public Base {
StaticMemberType GetStaticMember { return DerivedA::staticMemember; }
};
あるいはRTTI使ってマルチメソッド。

172:171
08/03/22 17:59:13
ごめん引数1つのマルチメソッドはないなw

173:デフォルトの名無しさん
08/03/22 18:22:26
あー、関数をアクセサにすればよかったですね。何やってんだ俺
ありがとうございました

174:デフォルトの名無しさん
08/03/22 21:56:34
>>170
どうもありがとうございます。実はその本は持っていて次に読む予定。
しかし、これも洞察には優れているとは思うけど、便利な本では
ないかも。面白そうなんで期待してるけど。

175:デフォルトの名無しさん
08/03/22 22:03:15
>>174
面白くないよ。mplの単なるリファレンス。

176:デフォルトの名無しさん
08/03/23 00:53:31
DLLを読み込み、一部の機能のみを使った場合、
メモリの消費量はまるまるDLL分増えるのでしょうか
それとも使った機能の分だけ増えるのでしょうか

177:デフォルトの名無しさん
08/03/23 01:03:35
環境依存の話はスレチだけど、まるまる増えると思うよ。

178:デフォルトの名無しさん
08/03/23 01:12:30
仮想メモリはまるまる
物理メモリはコードについては使った分
データはシラネ

179:デフォルトの名無しさん
08/03/23 01:30:13
ありがとうございました
使いたいライブラリが8MBくらいあるもので、
まるまる増えるのはちょっとアレかな、と思って質問しました
改変可なので、必要な部分だけ取り出そうと思います

180:デフォルトの名無しさん
08/03/23 03:06:24
Managerクラスがあり
その機能は、一部のクラス(と言っても10個ぐらいある><)
にしか利用できないって設計の場合
一部のクラスをfriendする以外に何か方法はありませんか?


181:デフォルトの名無しさん
08/03/23 03:13:01
その一部のクラス以外はmanagerクラスのインスタンスを手に入れられないようにする。

182:デフォルトの名無しさん
08/03/23 09:41:11
>>180
freind じゃダメな理由を書いた方が答えが得られやすいと思う。

183:>>182
08/03/23 09:42:51
ミスった... orz

freind ⇒ friend

184:デフォルトの名無しさん
08/03/23 09:45:07
friend先に依存が出来るからじゃね?
普通、friendは最終手段だし

185:デフォルトの名無しさん
08/03/23 12:07:26
そんなことはない。

186:>>182
08/03/23 13:05:05
friend 先に依存って何?

187:デフォルトの名無しさん
08/03/23 13:58:48
一部のクラスだけ特別扱いするというのがManagerクラスの仕様なら、
friendによる依存は妥当だと思う。

188:デフォルトの名無しさん
08/03/23 14:45:51
一部のクラスの基底クラスとして
Manager を取得するクラスを作って、
その1つだけを friend にすれば?

189:180
08/03/23 14:58:22
friendが結構な数になってしまうんです。
下手すれば私のリアルfriendより多いぐらい
それが悔しくて

190:デフォルトの名無しさん
08/03/23 14:59:16
誰が上手い事を言えと

191:184
08/03/23 15:01:24
俺は181に一票で

192:デフォルトの名無しさん
08/03/23 15:02:43
その方法を聞いてるんだろw

193:デフォルトの名無しさん
08/03/23 15:09:28
パスワード掛ければいいんじゃないですかね

194:デフォルトの名無しさん
08/03/23 15:14:48


195:デフォルトの名無しさん
08/03/23 15:25:03
権限プログラミングってのも面白そうじゃないか

196:デフォルトの名無しさん
08/03/23 15:42:23
singletonなら簡単なのにな


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

4571日前に更新/200 KB
担当:undef