C++相談室 part61

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。
2デフォルトの名無しさん:2008/03/09(日) 19:38:18
■基本■
[C++ FAQ]
 http://www.parashift.com/c++-faq-lite/
 http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
  Cとその仕様を比較しながらの解説なので分かりやすい。
  ***** 質問の前に必ずこの二つに目を通してください *****
[C/C++ リファレンス]
 http://www.cppreference.com/ (英語)
 http://www.cppll.jp/cppreference/ (↑の日本語訳だけど最新は反映しない)
[禿 Stroustrup]
 http://public.research.att.com/~bs/
[C++ International Standard]
 http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=38110
[JTC1/SC22/WG21 - C++]
 http://www.open-std.org/jtc1/sc22/wg21/
  ここから規格の最新(2003より新しい)ドラフトがダウンロードできる。
[JIS X3014]
 http://www.jisc.go.jp/app/pager?&RKKNP_vJISJISNO=X3014
  ISO規格の日本語訳。JIS X 3014:2003はISO/IEC 14882:2003 (E)に対応。
3デフォルトの名無しさん:2008/03/09(日) 19:38:41
4デフォルトの名無しさん:2008/03/09(日) 19:39:05
5デフォルトの名無しさん:2008/03/09(日) 19:39:25
STLつかうと一気に実行ファイルサイズが10倍に?!

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

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

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

#include <stdafx.h>
後死ね。

言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
6デフォルトの名無しさん:2008/03/09(日) 19:43:29
7デフォルトの名無しさん:2008/03/09(日) 19:46:54
>>6
サンクス、連投で制限食らった
8デフォルトの名無しさん:2008/03/09(日) 20:02:21
>>前スレ1000
とりあえず、お前が俺の言っていることを理解出来ていないことだけは分かった

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

一応補足
前スレ984のように聞いてみること自体は別に良いと思う
本を紹介してもらわないと先に進めない、ということでなければ
9デフォルトの名無しさん:2008/03/09(日) 20:05:41
お前のポリシーはどうでもいいよ
10デフォルトの名無しさん:2008/03/09(日) 20:06:48
そういや、こういうヤツがいるから初心者歓迎スレが出来たんだったな
11デフォルトの名無しさん:2008/03/09(日) 20:14:48
ポリシーじゃねぇよ・・・
無能にレスしても無駄のようだな・・・

>>10
初心者に本だけでなく入門サイト探してみたら?って言うのは
アドバイスにならないのか?
自分自身の経験から言っているんだけど
ある程度理解出来てくるとcppllのアーカイブとかも参考になるし
12デフォルトの名無しさん:2008/03/09(日) 20:31:24
おとなしく初心者歓迎スレかオススメ図書スレに誘導してやれよ
今回の様な議論が過去あったからこそそういったスレがあるんだから
13デフォルトの名無しさん:2008/03/09(日) 20:40:52
誘導済みだろ?
俺は別に質問者にレスしてるつもりないし・・・

前スレの985のレスが気に食わない人が居るようなので、
レス返してるだけ
14デフォルトの名無しさん:2008/03/10(月) 00:04:40
>>13
案外質問した人が突っ掛ってたりしてなw
んなわけないか。
15デフォルトの名無しさん:2008/03/10(月) 01:09:34
他スレでis-a、has-aで継承やメンバを考えるみたいな話が合ったんですが、
doはどういう風に処理したらいいでしょうか

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

このような機能を持つメソッドを、皆さんはどの位置に配置していますか?
16デフォルトの名無しさん:2008/03/10(月) 01:17:01
enemyのmoveメソッドはそのままで
WorldやGameからすべてのenemyのmoveメソッドを呼ぶ様にすればいいんじゃね?

ていうかC++関係ないな
17デフォルトの名無しさん:2008/03/10(月) 01:23:43
>>15
もし本当にゲームのことだったら
http://pc11.2ch.net/test/read.cgi/gamedev/1155209226/
とかで聞いた方が良さそう。
それかこの板のクラス設計とかのスレ。

俺だったら、大まかにStrategyパターン的な感じで書くかな。
enemyとかのユニット情報を持った環境(orフィールド)オブジェクトを
参照していじる敵戦略クラス・・・とか。
18デフォルトの名無しさん:2008/03/10(月) 01:31:46
>>16
すみません、自身がCからC++に移行して、
クラス設計に右往左往しているもので、ここで聞いてしまいました

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

moveメソッドは引数にしたがってオブジェクトの変数を変えるだけ
moveメソッドに渡す引数を敵戦略クラスないし、Worldクラスで決定するって方向で考えて見ます
(moveメソッドの内容が二行で終わりそうだ……。他のメソッドとまとめよう)
ありがとうございました
19デフォルトの名無しさん:2008/03/10(月) 01:34:51
>>18
ちなみに、17のはゲ製板のスレね。
20デフォルトの名無しさん:2008/03/10(月) 01:40:44
飛んできたのはおそらく同じ板のシューティング製作スレだなw
2117:2008/03/10(月) 02:11:11
ターン制で移動先選択→攻撃みたいなの想定してました/(^o^)\
敵戦略クラスは忘れた方が良いw
22デフォルトの名無しさん:2008/03/10(月) 03:05:22
Class().Method();

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

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

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

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

な感じ?
26デフォルトの名無しさん:2008/03/10(月) 22:47:08
一時オブジェクトが近々move semanticsな感じ?
27デフォルトの名無しさん:2008/03/10(月) 23:37:58
異なるクラスのオブジェクトをひとつの配列(vector,list)で管理することは出来ないのでしょうか
a[0]はclassA,a[1]はclassB,a[2]はclassC、……という風に
classA、classBは同じpublicなメンバを持っているのですが、
メンバ関数の中身とそこで使うprivateなメンバが異なっています
28デフォルトの名無しさん:2008/03/10(月) 23:49:47
>>27
そういうのこそ、ポリモーフィズムでしょ
29デフォルトの名無しさん:2008/03/10(月) 23:59:11
>>28
関数の多重定義のことでしょうか

ClassAとClassBの異なるメンバもひとつのクラスにまとめて、
使わないメンバがあっても気にしない、という方針でもいいんですが、
無駄にメモリを消費するのがイヤなもので
30デフォルトの名無しさん:2008/03/11(火) 00:01:24
全く関連のないクラスを1つの配列に入れるという時点でかなりおかしいと思う。
関連というか共通項があるからこそ1つの配列に入れるんだろう?
31デフォルトの名無しさん:2008/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デフォルトの名無しさん:2008/03/11(火) 00:09:10
boost::ptr_vector だと勝手に delete してくれるから楽だよ。
33デフォルトの名無しさん:2008/03/11(火) 00:43:37
>>30
アクションゲームで
A:単純な移動しかせず体当たりでダメージを生む敵
B:主人公の位置などを頼りに複雑なアルゴリズムで動き多彩な攻撃をする敵
こんな感じでAの方が圧倒的に必要なメンバ変数が少なく、
かつAの方が数が多いので、Bに合わせてメンバ関数を増やすとメモリを食らってしまうのです

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

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

あちがとうございました
34デフォルトの名無しさん:2008/03/11(火) 00:44:13
誤字修正
×Bに合わせてメンバ関数を
○Bに合わせてメンバ変数を
35デフォルトの名無しさん:2008/03/11(火) 02:31:06
>>33
とりあえず
継承、多態(ポリモーフィズム)、オーバーライド
等を調べるんだ

AとBの共通する部分を基本クラス(やinterface)としてくくりだせ
36デフォルトの名無しさん:2008/03/11(火) 11:10:02
エピステーメー氏の「C++言語のカラクリ」の話題出た?
なめて読んでたら「自己記述の必然性」が全く理解できない。
どうにか「だから単純なC++→C」のコンバーターじゃ駄目なんだよって
一言で説明できないか?
37デフォルトの名無しさん:2008/03/11(火) 11:49:30
C++をC++で記述できないとだめだということ?
何だかよく分からないな。でもあの人はたまに哲学よりのトンデモを平気で書いたりするから気にしちゃいけないよ。
38デフォルトの名無しさん:2008/03/11(火) 12:02:24
Cだけではtrr..catch..throwが実現できなかったって話だろ。
でも話題が古いなあ。
39デフォルトの名無しさん:2008/03/11(火) 12:23:12
自己記述できることが○○だ(スバラシイとか完備だとか)
って誰かに刷り込まれたんかな

頭悪いな
40デフォルトの名無しさん:2008/03/11(火) 12:26:33
コードジェネレータ通すとデバッグがやりにくそう
41デフォルトの名無しさん:2008/03/12(水) 00:28:22
VMのスタック上で記号処理を介せば
殆どの言語は自己記述可能だが

と書けばミもフタもないのか
42デフォルトの名無しさん:2008/03/12(水) 02:44:49
IO機能がないんですがどうすればいいですか。
43デフォルトの名無しさん:2008/03/12(水) 05:26:59
44デフォルトの名無しさん:2008/03/12(水) 05:33:36
42は41へのレスなんじゃなかろうか
45デフォルトの名無しさん:2008/03/12(水) 05:48:23
orz
46デフォルトの名無しさん:2008/03/12(水) 10:24:06
自己記述ってどんなの?
47デフォルトの名無しさん:2008/03/12(水) 11:16:52
ある言語やその処理系でその言語を実行できる処理系を書くことだお
48デフォルトの名無しさん:2008/03/12(水) 13:28:47
多分要はメタプログラミングは必要だから出てきたんだ、偶然や酔狂じゃない。
ってことを言いたいんだろ?読んでないけど。
49デフォルトの名無しさん:2008/03/12(水) 21:59:43
あれ?なんかtemplateで遊んでたらメタプログラミングできちゃったぞ

って感じ
50デフォルトの名無しさん:2008/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デフォルトの名無しさん:2008/03/12(水) 22:02:34
趣旨を間違った。
これじゃ普通にdmap[index]すればいいじゃねーか。

出直してくる。
52デフォルトの名無しさん:2008/03/12(水) 22:41:37
韓国人宇宙飛行士が国際宇宙ステーションに搭乗する際の活動に関する日本韓国間の協力について
http://www.enjoykorea.jp/tbbs/read.php?board_id=teconomy&page=3&nid=3433452&start_range=3433445&end_range=3433484

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

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

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

朝鮮人どもまじで死んでくれ。
53デフォルトの名無しさん:2008/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デフォルトの名無しさん:2008/03/13(木) 00:02:54
> it->first != key
これは問題なければ良いんだけど、正確にはlessを使えとかそういう話、無かったっけ?
55デフォルトの名無しさん:2008/03/13(木) 00:24:47
it->first != key
lower_boundの戻り値はpairじゃないよな。確かキーだよな。

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

if(it != map.end() || !(key < *it)) {
//found
} else {
//not found
}
56デフォルトの名無しさん:2008/03/13(木) 00:26:26
||じゃなくて&&だわ

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

57デフォルトの名無しさん:2008/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デフォルトの名無しさん:2008/03/13(木) 00:38:36
ごめん訂正。
- map<k, v>::value_typeがpair<k, v>
+ map<k, v>::value_typeがpair<const k, v>
59デフォルトの名無しさん:2008/03/13(木) 00:46:26
>>57
ああ、そうだね。elementの型がpairだた。スマソ。
60デフォルトの名無しさん:2008/03/16(日) 05:51:19
テスト
61デフォルトの名無しさん:2008/03/16(日) 05:55:48
class B;

class A
{
B b;
};

class B
{
A a;
};

と書いたところ、
エラー出ます><。
どう対処すればいいですか?
62デフォルトの名無しさん:2008/03/16(日) 06:04:28
よく考えようぜ。
A の中に B がある。
その B の中に A がある。
その A の中に B が・・・

あり得ない。


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

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

のどちらかになる。
63デフォルトの名無しさん:2008/03/16(日) 06:31:59
haskellを使う
64デフォルトの名無しさん:2008/03/16(日) 07:41:30
>>61
Aの中に持ちたいのはBそのものじゃなくて、Bの参照なんじゃね?
65デフォルトの名無しさん:2008/03/16(日) 15:02:01
>>62
循環して持ちたいのはよくあること。
やるなら>>64のようにすればいい。

同じような質問見つけてきたんで参考にどうぞ。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=36231&forum=7
66デフォルトの名無しさん:2008/03/16(日) 15:45:33
62にそう書いてるじゃん
67デフォルトの名無しさん:2008/03/17(月) 03:49:28
くだらない質問で申し訳ないのだけど、どなたか教えてください
クラスのコンストラクタで関数名の後ろにつけている初期化みたいなものの意味を教えてください

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

この場合だとa=0,b=0,c=0?
だとしたらなぜ...のところに書かないのですか?
68デフォルトの名無しさん:2008/03/17(月) 04:07:50
test
69デフォルトの名無しさん:2008/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デフォルトの名無しさん:2008/03/17(月) 04:29:44
変数とクラス名が同じだとエラー出るや

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

class hoge
{
A a;
public:
hoge() : a(0)
{
...
}
};
ってこと
この場合
...の所に a = 0; って書けない
71デフォルトの名無しさん:2008/03/17(月) 08:54:36
>>67
前者は初期化で、後者は何らかの初期化、または未初期化で構築の後、代入だな。
どちらでも良い場合はあるけど、意味は明確に違う。

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

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

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

未初期化な変数を嫌ったり、デフォルトコンストラクタの後に代入するような
効率の悪さを嫌ったり、色々あるからできるだけ初期化を使う。
72デフォルトの名無しさん:2008/03/17(月) 10:11:47
CとC++の違いを徹底解説!みたいな本に
Class::Method():field(0),field1(0)
{
}
なんて書いてあってさ、
何だよコンパイラバグってんじゃねーか!とか思ったころがあった
73デフォルトの名無しさん:2008/03/17(月) 10:39:23
>>72 本の名前晒しといてくれ。
74デフォルトの名無しさん:2008/03/17(月) 10:40:42
ていうかさ、constメンバや参照メンバもそうだけど
基底クラスの初期化も、この形式じゃないと出来ないよ。

もちろん、引数なしのデフォルトコンストラクタでの初期化は可能だけど。
7572:2008/03/17(月) 11:55:05
「オブジェクト指向言語C++入門 Cとの違いを徹底追求」
これかな。
やっぱり古いのもあってか、<string.h>とか、
namespace、例外の話はまったくなかった。
それ意外と、多少の誤植を除けば、解り安くもなければ解りづらくもない中立的な本だった。

まぁ、今となっては読むべき本じゃないわな
76デフォルトの名無しさん:2008/03/17(月) 13:02:50
低レベルな質問は初心者スレでやれ
77デフォルトの名無しさん:2008/03/17(月) 15:16:38
>>76
おまえが、↓に行け

C++上級者が集まるスレ
http://pc11.2ch.net/test/read.cgi/tech/1095113801/
78デフォルトの名無しさん:2008/03/17(月) 16:49:26
関数の戻り先アドレスがバッファオーバーランで壊されているようなんですが、どこで壊されているのかが分かりません。

a(){

b();

}

b(){

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

/* 処理1 */

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

/* 処理2 */

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

return;
}

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

もし分かりましたら、参照方法を教えてください。
よろしくお願いします。
79デフォルトの名無しさん:2008/03/17(月) 17:02:46
環境に依存します
80デフォルトの名無しさん:2008/03/17(月) 17:17:10
>>78
そこまで推測できているならデバッガでスタックにトリガ張ればすぐだろうし、
そうでなくてもコンパイラにスタックのチェックをするオプションがあったりしないか?
そもそもバッファオーバフローだと判っているなら関数内のポインタを全部洗えばいいだけじゃん。
# 巨大関数だったらしらねw
81デフォルトの名無しさん:2008/03/17(月) 17:27:32
>>79
失礼しました。
Windows2000 VC++6です。

>>80
それが、1ヶ月に1度位しか発生しないエラーなのでトレースが困難なんです。
各所にログを埋め込み、関数から戻ってこないのは確認できたので、戻り先アドレスが壊されているらしいと推測したんです。
次はどこで壊されるかをログに記録し、また1ヶ月待ってみようと思いましてw
82デフォルトの名無しさん:2008/03/17(月) 17:30:16
espでも記録しておくとか
83デフォルトの名無しさん:2008/03/17(月) 17:46:56
>>81
>79の時点でスレ違いだと気付こう。
>そうでなくてもコンパイラにスタックのチェックをするオプションがあったりしないか?
84デフォルトの名無しさん:2008/03/17(月) 18:21:17
>>83
申し訳ありませんでした。
色々なアドバイスありがとうございました。
85デフォルトの名無しさん:2008/03/17(月) 21:45:50
const T &なメンバをもつクラスを作ったんだが、
ひょっとして、コピーする手段がない?
86デフォルトの名無しさん:2008/03/17(月) 21:51:54
クラス初期化にしかconst T &は初期化できないから
まぁなんというか頑張れ
87デフォルトの名無しさん:2008/03/17(月) 22:03:17
コピーコンストラクタならおkだが、operator=はダメだろうな
88デフォルトの名無しさん:2008/03/17(月) 22:47:28
const_ca
89デフォルトの名無しさん:2008/03/18(火) 00:27:05
なんで&があるん?
*だけじゃ駄目なん?
90デフォルトの名無しさん:2008/03/18(火) 01:01:24
駄目です
91デフォルトの名無しさん:2008/03/18(火) 01:23:09
なんで
92デフォルトの名無しさん:2008/03/18(火) 01:24:56
インラインアセンブラ使えばコピーできないことはないだろうが
当然おすすめはしない。
93デフォルトの名無しさん:2008/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デフォルトの名無しさん:2008/03/18(火) 01:53:29
X::valはYから見ればprivate
Y::X::valはYから見ればpublic
95デフォルトの名無しさん:2008/03/18(火) 01:55:26
あ、いや、privateというべきじゃなくprotectedでいいのかな。どっちだろ。
いずれにせよYからX::valは触れない。Y::X::valなら触れる。
9693:2008/03/18(火) 02:05:40
>>95
やっぱりそうですか。なんとなく奇妙な言語仕様に思えるのですが。。。
97デフォルトの名無しさん:2008/03/18(火) 02:21:17
じゃなぜこういう風に難解なルールになっているか逆に考えてみればわかる。

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

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

モジュールの隠蔽が破られないように特別なルールが作られているわけだ。
9893:2008/03/18(火) 02:33:25
なるほど。なんとなくですが、分かりました。
99デフォルトの名無しさん:2008/03/18(火) 07:13:26
fseekgでstr.length()分を戻したいのですけど、
単にマイナスをつけて、-str.length()とするとイミフな数値しか出ません。
何でうまくいかないんでしょうか?
100デフォルトの名無しさん:2008/03/18(火) 07:39:13
事故解決しました。 length()が返すのはsize_typeで、
size_typeはsize_tのunsigned intみたいだからですね。
101デフォルトの名無しさん:2008/03/18(火) 20:26:40
出しかたによる。
102デフォルトの名無しさん:2008/03/18(火) 20:37:42
>>100
環境依存の話すんなくそったれ
103デフォルトの名無しさん:2008/03/18(火) 22:02:40
この言語機能多すぎじゃね?
104デフォルトの名無しさん:2008/03/18(火) 22:14:29
必要な部分だけ使え
105デフォルトの名無しさん:2008/03/18(火) 22:23:31
>>102
少なくともsize_typeは符号無しということは標準で決まっている事柄だったと思う。
106デフォルトの名無しさん:2008/03/18(火) 23:49:31
>>105
unsigned intとどこに書いてある?
107デフォルトの名無しさん:2008/03/19(水) 00:00:40
お前は何を言ってるの?
108デフォルトの名無しさん:2008/03/19(水) 00:22:24
>>106
それは規格のどこにも書いていないが、
例えばもし99=100が使っている実装のsize_typeが
仮にunsigned longやunsigned shortだったとしても、
99=100は同じように質問して同じように解決していたに違いない。

たまたま100の使っている実装でsize_typeがunsigned intだったこと以外は
標準C++で普遍的に成り立つ話じゃないか。
109デフォルトの名無しさん:2008/03/19(水) 00:24:39
size_typeは符号なし整数。
ただしbit数は決まってない。
110デフォルトの名無しさん:2008/03/19(水) 06:33:43
>>108
頭の悪い子って、「話の行きがかりで登場したディテール」と「そのディテールに依存した話」の違いが
わからないから困るよね。

少なくとも、「環境依存の話すんなくそったれ」と「unsigned intとどこに書いてある?」の2レスより、
「でも規格で決まってるのはunsignedってことだけだから注意」とか書くほうが簡潔で有用。
非・馬鹿は最初からこう書く。
111デフォルトの名無しさん:2008/03/19(水) 07:24:46
size_t が unsigned long のこともよくあるしな。
112デフォルトの名無しさん:2008/03/19(水) 09:04:06
unsigned short だったりすると -length() しても int 型で普通に負の数になったりして。
113デフォルトの名無しさん:2008/03/19(水) 12:28:38
std::cinで文字や数値を入力するとバッファに改行文字が残るようで、
その後に std::getline(std::cin, buf, '\n'); とかやらせると残った改行文字だけ読み込んでしまいます。
バッファをクリアする方法がないかと調べてみたのですが、
環境に依存せず確実にクリアする方法はない、という記述がありました。

こういう場合はそもそもstd::cinを使わないようにするのがよいのでしょうか?
fgetsとかを代わりに使えば改行文字まで読み込んでくれるみたいなのですが、
std::cinの方がすっきりしたコードになるので、他に問題を回避する方法がないか探しています。
114デフォルトの名無しさん:2008/03/19(水) 12:45:02
>>113
cin.ignoreを呼ぶとかcin.getを繰り返すとかで十分では?
115デフォルトの名無しさん:2008/03/19(水) 12:49:09
ああ、なるほど。
この場合はバッファに残るのが改行文字一個だけと分かってるから、それで十分なんですね。
ありがとうございました。
116デフォルトの名無しさん:2008/03/19(水) 15:15:14
cinから一行読み込み+istringstreamで良くね?
string line;
getline(cin,line);
stringstream linestream(line);
117デフォルトの名無しさん:2008/03/20(木) 15:40:59
#define Max 1000

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

const int Max = 1000;

とした方が良い(型指定ができるから)、と読んでる本で出てきました。
色んな所で「グローバル変数はできるだけ使うな」と言われていたのでびっくりしてしまったのですが、
こうやってconstにして#defineの代わりにするのは例外的によく使われるものなのでしょうか?
118デフォルトの名無しさん:2008/03/20(木) 15:46:50
defineよりはマシってだけの話。
119デフォルトの名無しさん:2008/03/20(木) 15:52:08
グローバル変数の議論とはまた別の話しだろ
120デフォルトの名無しさん:2008/03/20(木) 15:56:36
>>117
グローバル変数がダメなだってだけ覚えてて、なぜダメなのか考えたこと無いみたいだね?
大雑把に言うとどこで変更してるか分からないから把握しづらいといったとこです

const つけた場合(やろうと思えばできるけれど)変更できないので、そういう害は無い
121デフォルトの名無しさん:2008/03/20(木) 15:58:48
あほすぎるw
122デフォルトの名無しさん:2008/03/20(木) 16:53:57
別の翻訳単位で参照する可能性のある“変数”ならグローバル変数を使う。
別の翻訳単位で参照する可能性のある“数値”なら#define定義のあるヘッダを各自インクルードすればいい。
123デフォルトの名無しさん:2008/03/20(木) 17:11:37
>>122
なに言ってんの?w
124デフォルトの名無しさん:2008/03/20(木) 17:12:31
const ついてるやつはグローバル定数と呼ぶべきもの。
125デフォルトの名無しさん:2008/03/20(木) 17:17:00
>>117
グローバル変数に限らず、「○○はよくない」などと言われる物は絶対にダメという意味ではない。
○○以外の有効な手段があればそれを選べという意味であって、○○が有効となる限られたケースでは使っていい。
126デフォルトの名無しさん:2008/03/20(木) 17:18:31
理由を理解せずに規約に従っても意味がない事の典型だな
127デフォルトの名無しさん:2008/03/20(木) 18:31:27
>117
基本的にマクロは(特定の使い方以外)使わない方がいい。
マクロはプリプロセスで処理されてしまうため、コンパイルエラー時に酷い目に会う。
グローバル変数も使い方が難しいけど、コンパイラが識別できるものなのでマクロより余っ程マシ。
エラーが発生してもあくまで“変数”なので、マクロと違って識別名が普通に表示されるので
トレースしやすい。

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

……しかし、こういう「疑問点を自ら追求する力を付ける」のがゆとり教育だったはずなんだけどね。
やっぱり失敗だったのか……
128デフォルトの名無しさん:2008/03/20(木) 18:37:15
なんで勝手に117をゆとり教育を受けた人認定してるんだよ
129デフォルトの名無しさん:2008/03/20(木) 18:41:28
エスパーするとC++でなく、Cの人が居ます。
「const リンケージ」でググって下さい。

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

グローバル変数が嫌われる主な理由は、
どこで書き換えられるか、把握し辛いことにあるため、
定数には当てはまりません。
130デフォルトの名無しさん:2008/03/20(木) 18:56:40
どう見てもゆとりです、本当にありがとうございました。
131デフォルトの名無しさん:2008/03/20(木) 20:02:06
1. マクロ定数はアドレスを完全に持たない。
 (const 定数はアドレスを取得しようと思えばできるが、
  アドレスを取得しさえしなければデータがデータメモリ上に置かれるとは限らない)

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

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

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

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

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

7. const 定数を使うと副作用が一切無いことが明示される。
 (キャスト演算子をオーバーロードしているクラスのオブジェクトの場合は例外だが)
132デフォルトの名無しさん:2008/03/21(金) 11:21:21
質問があります。

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

delete [] p;

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

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

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

ポインタpそのものは先頭1バイトのアドレス情報しか保持して
ませんから、こういう疑問をもった次第です。
133デフォルトの名無しさん:2008/03/21(金) 11:30:24
ポインタそのものにそのアドレスに何が格納されてるかの情報は含まれてる。
そうでなければ cout << *p << endl; とかやったときに何が表示されるか未定義になってしまうじゃないか。
134デフォルトの名無しさん:2008/03/21(金) 12:15:53
>ポインタそのものにそのアドレスに何が格納されてるかの情報は含まれてる。

ありがとうございます。

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

という理解でよろしいでしょうか?
135デフォルトの名無しさん:2008/03/21(金) 12:21:02
>>134
違う。ポインタの型によって静的に決まる
136デフォルトの名無しさん:2008/03/21(金) 12:21:50
静的に型付けされてるからそんなものは要らない。
137デフォルトの名無しさん:2008/03/21(金) 12:23:04
まさかvoid*をdeleteしてないよな…
あとポインタが4バイトとは限らないぞ。
138デフォルトの名無しさん:2008/03/21(金) 12:30:09
うーん、わからなくなってきました。

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

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

この段階にくると、コンパイラやアセンブラが理解できないと
無理なんでしょうけど。
139デフォルトの名無しさん:2008/03/21(金) 12:50:07
実行時に要素のバイト数は、どこにも格納されてない。
と、考えて良い。

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

※RTTIは上記が理解出来た上で。
140デフォルトの名無しさん:2008/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デフォルトの名無しさん:2008/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デフォルトの名無しさん:2008/03/21(金) 13:25:59
>>141
p[i]のpの型はコンパイル時に分かってるんだから
143デフォルトの名無しさん:2008/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デフォルトの名無しさん:2008/03/21(金) 13:56:21
>>141
> p[i]のアクセス
たとえばintが4byteの環境だとすると、p[i] と書かれた箇所はネイティブコードにおいては
「pのアドレス+i*4byteのメモリアドレスへ行ってそこから先4byte分に書き込まれているビット配列を〜」
という風に、既にintが「4byte」というミもフタも無い表現に変わっているから、型情報も何も関係無いよ。
145デフォルトの名無しさん:2008/03/21(金) 14:27:51
>>141
p[i]というコードはコンパイルすると、アドレスはp+4*iといった意味の命令が生成される。
4が出てくる理由はpの宣言int* pによるもの(intが4byteの環境の場合)。
146145:2008/03/21(金) 14:36:28
すまん、144と同じ事書いてしまった。
147141:2008/03/21(金) 17:03:54
返事が遅くなってすみません。みなさん、ありがとうございます。

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

4byteという要素バイト数の情報をポインタp自体が保持して
いるのではなく、p[i]にアクセスする際にコンパイラがp+4*i
を計算する命令を生成しているだけ、ということがやっと理解
できました。
148デフォルトの名無しさん:2008/03/21(金) 18:35:45
配列 new の場合、アップキャストは行わないから
配列のサイズは型から静的に決まる、と。
というか、アップキャストはできない。
そこが鍵だな。
149デフォルトの名無しさん:2008/03/21(金) 18:36:13
×配列のサイズ
○要素のサイズ
150デフォルトの名無しさん:2008/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デフォルトの名無しさん:2008/03/21(金) 18:48:30
atofで一つずつ進めて数値になる所を取り出す
152デフォルトの名無しさん:2008/03/21(金) 18:51:36
それはないな
153デフォルトの名無しさん:2008/03/21(金) 19:53:08
自分で字句解析器を書く。
154デフォルトの名無しさん:2008/03/21(金) 20:00:28
各種正規表現ライブラリの後方参照を使う
155デフォルトの名無しさん:2008/03/21(金) 20:29:16
>>150
そういうのが必要になる状況ってあまり無くない?
156デフォルトの名無しさん:2008/03/21(金) 21:08:24
>>155
俺はソースコード解析したい時によくでる。
字句解析ライブラリもってこいって話だよな・・・
157デフォルトの名無しさん:2008/03/21(金) 21:51:06
字句解析なら分かるんだけど、>>150は何か違う気がしたんで・・・
そうなら、分割の話から入るだろうし。

もしかして自然言語文からの抽出とかかな?
158150:2008/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デフォルトの名無しさん:2008/03/22(土) 00:19:27
>主にデータファイルをフォーマットし直したり
それまさに字句解析の範疇な気がするけど・・・w

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

regex ってかなり強力だと思う。テキストから情報拾う場合
に regex では簡単に通用しない場合ってどういうケース?
161デフォルトの名無しさん:2008/03/22(土) 13:14:39
>>160
ネストした括弧の対応を取るとか
162デフォルトの名無しさん:2008/03/22(土) 14:07:16
そこでboost::xpressiveですよ
163デフォルトの名無しさん:2008/03/22(土) 14:15:50
boost もいろいろあってわからんなぁ。xpressive だと簡単なのかな。

俺だと char ごと読み取って '(' ')' を +1, -1 でカウントするとか
低レベルな事を考えちゃうけど。
164デフォルトの名無しさん:2008/03/22(土) 14:52:00
 通常の正規表現では任意のネストを表現することができない。
→xpressive ではパターンの自己再帰記述が可能。
→正規表現の枠を超える表現力を持つ(文脈自由文法)。
→xpressive だとネストの対応が可能。
165デフォルトの名無しさん:2008/03/22(土) 15:01:28
boostの文字列処理ライブラリの事ならboost本のサンプルで読めたな
166デフォルトの名無しさん:2008/03/22(土) 15:21:10
boost 本でお薦めってある? 本あまり出てないよね。

Karlsson の本は目を通したけど感じは判ってよいけど便利な本
という感じではない。秀和から出てる稲葉さんは本厚いし内容あるのかな。
167デフォルトの名無しさん:2008/03/22(土) 17:31:22
inabaさんのは導入+軽いリファレンスにはいいかも
おおまかな概念と使用例が載ってる
boostもう使ってるよ〜という人にはあまり必要ないかも
168デフォルトの名無しさん:2008/03/22(土) 17:31:23
複数の派生クラスがそれぞれ値の異なるconst staticなメンバ変数をもっていて、
基底クラスへのポインタを使って読み取りたいのですが、どうすればいいでしょう
基底クラスへのポインタの配列に、いろいろな派生クラスを突っ込んでいる状態なので、
直接アクセスすることは出来ません
169デフォルトの名無しさん:2008/03/22(土) 17:49:42
170デフォルトの名無しさん:2008/03/22(土) 17:54:12
>>166
C++ Template Metaprogramming
171デフォルトの名無しさん:2008/03/22(土) 17:56:20
>>168
普通に仮想関数で
struct Base { virtual StaticMemberType GetStaticMember()=0; };
struct DerivedA : public Base {
StaticMemberType GetStaticMember { return DerivedA::staticMemember; }
};
あるいはRTTI使ってマルチメソッド。
172171:2008/03/22(土) 17:59:13
ごめん引数1つのマルチメソッドはないなw
173デフォルトの名無しさん:2008/03/22(土) 18:22:26
あー、関数をアクセサにすればよかったですね。何やってんだ俺
ありがとうございました
174デフォルトの名無しさん:2008/03/22(土) 21:56:34
>>170
どうもありがとうございます。実はその本は持っていて次に読む予定。
しかし、これも洞察には優れているとは思うけど、便利な本では
ないかも。面白そうなんで期待してるけど。
175デフォルトの名無しさん:2008/03/22(土) 22:03:15
>>174
面白くないよ。mplの単なるリファレンス。
176デフォルトの名無しさん:2008/03/23(日) 00:53:31
DLLを読み込み、一部の機能のみを使った場合、
メモリの消費量はまるまるDLL分増えるのでしょうか
それとも使った機能の分だけ増えるのでしょうか
177デフォルトの名無しさん:2008/03/23(日) 01:03:35
環境依存の話はスレチだけど、まるまる増えると思うよ。
178デフォルトの名無しさん:2008/03/23(日) 01:12:30
仮想メモリはまるまる
物理メモリはコードについては使った分
データはシラネ
179デフォルトの名無しさん:2008/03/23(日) 01:30:13
ありがとうございました
使いたいライブラリが8MBくらいあるもので、
まるまる増えるのはちょっとアレかな、と思って質問しました
改変可なので、必要な部分だけ取り出そうと思います
180デフォルトの名無しさん:2008/03/23(日) 03:06:24
Managerクラスがあり
その機能は、一部のクラス(と言っても10個ぐらいある><)
にしか利用できないって設計の場合
一部のクラスをfriendする以外に何か方法はありませんか?
181デフォルトの名無しさん:2008/03/23(日) 03:13:01
その一部のクラス以外はmanagerクラスのインスタンスを手に入れられないようにする。
182デフォルトの名無しさん:2008/03/23(日) 09:41:11
>>180
freind じゃダメな理由を書いた方が答えが得られやすいと思う。
183>>182:2008/03/23(日) 09:42:51
ミスった... orz

freind ⇒ friend
184デフォルトの名無しさん:2008/03/23(日) 09:45:07
friend先に依存が出来るからじゃね?
普通、friendは最終手段だし
185デフォルトの名無しさん:2008/03/23(日) 12:07:26
そんなことはない。
186>>182:2008/03/23(日) 13:05:05
friend 先に依存って何?
187デフォルトの名無しさん:2008/03/23(日) 13:58:48
一部のクラスだけ特別扱いするというのがManagerクラスの仕様なら、
friendによる依存は妥当だと思う。
188デフォルトの名無しさん:2008/03/23(日) 14:45:51
一部のクラスの基底クラスとして
Manager を取得するクラスを作って、
その1つだけを friend にすれば?
189180:2008/03/23(日) 14:58:22
friendが結構な数になってしまうんです。
下手すれば私のリアルfriendより多いぐらい
それが悔しくて
190デフォルトの名無しさん:2008/03/23(日) 14:59:16
誰が上手い事を言えと
191184:2008/03/23(日) 15:01:24
俺は181に一票で
192デフォルトの名無しさん:2008/03/23(日) 15:02:43
その方法を聞いてるんだろw
193デフォルトの名無しさん:2008/03/23(日) 15:09:28
パスワード掛ければいいんじゃないですかね
194デフォルトの名無しさん:2008/03/23(日) 15:14:48
195デフォルトの名無しさん:2008/03/23(日) 15:25:03
権限プログラミングってのも面白そうじゃないか
196デフォルトの名無しさん:2008/03/23(日) 15:42:23
singletonなら簡単なのにな
197デフォルトの名無しさん:2008/03/23(日) 16:01:39
思い出したw

____
|← reject|  boostの中の人  singleton   ユーザー
. ̄.|| ̄ ̄        ┗(^o^ )┳(`Д´)┳(^o^ )┛≡=-
  ||            ┏┗   ┗┗  ┏┗ ≡=-
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
198デフォルトの名無しさん:2008/03/23(日) 16:06:07
ユーザーは欲してると思うが
199デフォルトの名無しさん:2008/03/23(日) 16:34:52
にわかに得た知識で面白いこと考えた!
Managerのインスタンスを受け取る関数の引数に関数オブジェクトを使って
内部で一定のアルゴリズムで正しい値を返すもの(パスワードの暗号化みたいな)にのみそのインスタンスを渡してやる風にすればいいんじゃね?
更にインスタンスを受け取る関数をテンプレート化してやり、欲しい権限までのクラス型インスタンスを返すようにしてやればアクセス制限も出来て完璧!


とここまで考えてわざわざこんなことしてもオーバーヘッドが大きいだけなことに気づいた
そもそも何の意味があるんだっけか
200デフォルトの名無しさん:2008/03/23(日) 16:45:12
だから >>188 でいいだろ、別に。
201デフォルトの名無しさん:2008/03/23(日) 16:57:35
Managerクラスコンストラクタなどをprotectedにして、使うクラスはManagerを継承する。
202デフォルトの名無しさん:2008/03/23(日) 17:02:41
>>188 >>199 >>201
これらの方法は、Managerクラスの許可なく好き勝手に権限のあるクラスを作れる。
そういうのを>>180は制限したいんじゃないの?
203>>182:2008/03/23(日) 17:08:28
>>201
そう言うのは最悪。

あとから見て、継承が本当に必要だったのか、単に特定のメソッドを
使わせるために継承しているのかがわからなくなるから。
204201:2008/03/23(日) 17:21:39
>>203
意味がよく分からないけど、、、「特定にメソッドを使わせるために継承が必要かどうかがわからなくなる」ってこと?
そんなこと言ってたら何もできない。
friendだったら、なぜfriendにしたか分からなくならないの?

friend よりいいと思うけどな。
friend じゃprivateのメンバにアクセスできてしまう。

Managerクラスを機能を利用するんだから、継承しかないでしょ。
使う側のクラスに持たせるとなると、コンストラクタとかはpublicになってしまうし。
205デフォルトの名無しさん:2008/03/23(日) 17:40:32
継承すると
Managerの中のstaticでない変数とか勝手に作られない?
206デフォルトの名無しさん:2008/03/23(日) 17:41:03
>>203
Manager クラスじゃなくて単に許可コントロール用の class を作る
というのは有りじゃない?そういう例をまともな本で見た記憶がある。
207デフォルトの名無しさん:2008/03/23(日) 17:42:27
-カーズは-
2度と地球へは戻れなかった…。
鉱物と生物の中間の生命体となり
永遠に宇宙空間をさまようのだ。

そして死にたいと思っても死ねないので
―そのうちカーズは考えるのをやめた。

全部globalにすればいいじゃん
208デフォルトの名無しさん:2008/03/23(日) 17:44:01
>>206
電波の缶詰の人のサンプルもそうだった

ライブラリ的なものを
外部からいじられないようにするためだったら
そんな感じでもいいんじゃまいか

村八分
209デフォルトの名無しさん:2008/03/23(日) 17:47:19
Managerインスタンスを受け取るために、Managerにコールバックしてもらえばいいんじゃない?
class FriendClassA; // 前方宣言
class FriendClassB;
class Manager
{
public:
  class Friend { public: virtual void authorize(Manager* m) = 0; };
  void getInstance(Friend* p)
  {
    if( dynamic_cast<FriendClassA*>(p) ||
        dynamic_cast<FriendClassB*>(p) ||
        /* 権限のあるクラスかをチェック */ )
    {
      p->authorize(this);
    }
  }
};
210デフォルトの名無しさん:2008/03/23(日) 18:25:34
それは、インスタンス取るのに時間かかるし
friendでいいじゃんって話になるも
211デフォルトの名無しさん:2008/03/23(日) 18:40:51
速度が重要ならtemplate部分特殊化とかで。

class Manager
{
public:
template <class Unauthorized>
static void authorizedProc(unauthorizedClass * p)
{ std::cout << "not authorized" << std::endl; }
template <>
static void authorizedProc(authorizedClassA * p)
{ p->Proc(m_instance); }
// 以下許可するクラス分同じコード
private:
Manager m_instance;
};

冗長だし検証してないけど。
212デフォルトの名無しさん:2008/03/23(日) 18:45:30
Manager を使えるクラスを作成する場合には
ファクトリクラスを通すようにする。
で、そのファクトリクラスを friend にして、
そこで Manager クラスを取得して、
各クラスにそれを渡すようにする。
設定関数は各クラスの共通基底クラスに作って、
それをファクトリクラスの friend にする。
213デフォルトの名無しさん:2008/03/23(日) 18:46:54
先輩から聞いたのですが、extern "C" {}せずに構造体を宣言すると、
余計なクラス情報がくっつくって本当ですか?
214デフォルトの名無しさん:2008/03/23(日) 18:52:41
そんなことは聞いた事が無いが、
特定のコンパイラでそういう事があるとかいうんだったら俺は知らない。
215デフォルトの名無しさん:2008/03/23(日) 18:55:11
クラス情報って具体的には何なんだ?
216デフォルトの名無しさん:2008/03/23(日) 18:57:34
>>213
マングリング名にクラス情報がくっつくって話だと思う。
217デフォルトの名無しさん:2008/03/23(日) 18:59:55
>>214-216
言ってたのはシリコンバレー帰りの先輩です
純粋なCの構造体にするにはやはりextern "C"が必要なのですね。
ありがとうございました。
218デフォルトの名無しさん:2008/03/23(日) 19:00:36
>>217
どこからそういう判断をしたんだ?w
219デフォルトの名無しさん:2008/03/23(日) 19:01:52
構造体にextern "C"は関係無いだろ
220デフォルトの名無しさん:2008/03/23(日) 19:02:10
>>216
構造体名って C でそもそも何らかのマングリングされるの?
221デフォルトの名無しさん:2008/03/23(日) 19:07:59
C++なら名前空間やらなんやらくっつくだろ。
222デフォルトの名無しさん:2008/03/23(日) 19:10:41
C で付かないなら
純粋な C の構造体かどうかなんて
どう区別するんだろうか。
223>>182:2008/03/23(日) 19:46:38
>>204
まじめな話、もう一度継承についてちゃんと勉強した方がいいと思う。
(>>205 の内容を理解できてる?)

継承はアクセス制限のためにあるものじゃない。
極端な話、全てが public であったとしても、継承は有用。

これに対して、friend は純粋にアクセス制限を回避するもので、かつ
アクセス制限を回避する以外の機能は無いから、なぜ friend にしたか
がわからなくなることはない。
(もちろん、なせアクセス制限を回避する必要があるかはどっかに書いて
おく必要があるだろうけど。)

>>206
それならアリだと思う。
224201:2008/03/23(日) 19:54:02
>>223
>>205
作られるけど。外から参照されたくないものはpublicにしなけらばいいじゃん
225201:2008/03/23(日) 20:00:37
>>223
>継承はアクセス制限のためにあるものじゃない。
>極端な話、全てが public であったとしても、継承は有用。

だから、継承が駄目なんですか?
継承は色んな意味で使えて「わかりにくい」から駄目ってこと?
226デフォルトの名無しさん:2008/03/23(日) 20:00:37
何かもう駄目だなここって思ったの俺だけだろうか
227デフォルトの名無しさん:2008/03/23(日) 20:02:29
Manager 使ってる部分を別プロジェクトにする。
あとは各クラスのオブジェクト生成を外部から隠せばいい。
228>>182:2008/03/23(日) 21:01:54
>>224
> 作られるけど。外から参照されたくないものはpublicにしなけらばいいじゃん

おいおい、ほんとにもう少し勉強してからこいよ。
引っ込みつかなくなってるだけならいいけど、マジでそう思ってるとしたら
ちょっとまずいよ。

まずい理由の一つは、private でもその変数が見えなくなるわけじゃない、
アクセスできなくなるだけだから。

この違いわかってる?

>>225
> 継承は色んな意味で使えて「わかりにくい」から駄目ってこと?

>>203 に書いたのはそう言うこと。

それしか方法が無いならしょうがないけど、friend と言うもっといい方法があ
るのにわざわざ使わないのは、別の意図があるようにとられる危険性が高い。
229201:2008/03/23(日) 21:17:23
>>228
>マジでそう思ってるとしたらちょっとまずいよ。

Managerを継承していないクラスから参照されたくない場合はpublicにすれば良いって事だよ?

>まずい理由の一つは、private でもその変数が見えなくなるわけじゃない、
>アクセスできなくなるだけだから。

「見える」→メンバ変数の値が取得できる。(getter)
「アクセス」→メンバ変数の値が書きかえれる。(setter)
って意味で言ってるのなら
getter、setter定義してやれば、当然見えるしアクセスも可能。

230デフォルトの名無しさん:2008/03/23(日) 21:42:53
もしかして201氏は、
Managerは1つのクライアント(Managerを使うクラスオブジェクト)の管理のみ引き受けるもので、
クライアントと同数のManagerオブジェクトが必要と考えているのではないだろうか。
231>>182:2008/03/23(日) 22:07:14
>>229
> 「見える」→メンバ変数の値が取得できる。(getter)
> 「アクセス」→メンバ変数の値が書きかえれる。(setter)

ほら、全然理解できてない。

簡単な例でいうと、

int a, b;

class X {
private: int a;
};

class Y: public X {
 int foo(){ return a; }
 int bar(){ return b; }
};

ってやると、foo() の中で X::a をアクセスしようとするからエラーになるよね。

もし、C++ の private が変数を「見えなくする」なら bar() の b と同じように、
foo() は ::a を返すはずだろ?

これが、「見えなくなること」と「アクセスできなくなること」の違いなわけ。

これによる、影響は自分で調べてみてね。

>>230
まあ、それはそれでそれこそもっとよく考えろとしか言えないわけだが...
232デフォルトの名無しさん:2008/03/23(日) 22:11:42
何でこんな残念なスレになってしまったんだ。
233デフォルトの名無しさん:2008/03/23(日) 22:12:43
だって にちゃん だもの
234デフォルトの名無しさん:2008/03/23(日) 22:56:01
VSyncの話したらひどいことになりそう
235デフォルトの名無しさん:2008/03/23(日) 22:57:56
>>231
初心者スレでやれ
ウザイ
236デフォルトの名無しさん:2008/03/23(日) 23:03:27
結局>>182って文句言ってるだけで答えて無いじゃん
237>>182:2008/03/23(日) 23:14:58
答えは >>188 で既にでてるだろ。

まあ、10個ぐらいなら全部 friend 宣言してもいいと思うけど。

もしかして君も >>201 みたいに理解できてないやつなの? (w
238デフォルトの名無しさん:2008/03/23(日) 23:32:29
>>188だとManager::getInstanceみたいなので取得するのと大差無いと思うが・・・

まぁ、それはともかく、>>180にfriendなどを使ってまで
制限する必要性があるのか、疑問だな。
クラスごと使わせなくするとこにfriendを使用している時点でおかしいと思う。

無名名前空間やdetails名前空間で十分なんじゃないか?
239201:2008/03/23(日) 23:44:18
>>231
>foo() の中で X::a をアクセスしようとするからエラーになるよね。

アクセッサをManagerの方に定義することを考えていたんだけどな。
「見える」「見えない」の話じゃんくてprivateだからだろ。

>もし、C++ の private が変数を「見えなくする」なら bar() の b と同じように、
foo() は ::a を返すはずだろ?

グローバル変数よりメンバ変数を参照しにいくのは知ってます。

Managerの方に「一部のクラス」に使わせたい機能だけ、protected または public にして
一部のクラスがManagerを継承すればいい。

Manager のprivateのメンバには「一部のクラス」も参照できない。

「一部のクラス」以外にManagerクラスのインスタンスを作られるのが困る場合は
コンストラクタなどをprotectedにすればいいんでは?


「一部のクラス」に対してManagerは一つらしいので、また違ってきますが・・・・
240デフォルトの名無しさん:2008/03/23(日) 23:58:52
これで friend いらない

-- friends.cpp
#include "A.h"
#include "B.h"

namespace
{
class Manager {};
Manger& manager();
}


void A::f() { manager().a(); }

void B::g() { manager().b(); }
241>>182:2008/03/24(月) 00:06:26
>>238
> まぁ、それはともかく、>>180にfriendなどを使ってまで
> 制限する必要性があるのか、疑問だな。

それは、>>180 に聞いてもらわないとダメだけど、そう言う状況はありえると思うよ。

例えば、デバッグのためにマネージャの状態を直接見たりいじったりするクラスとか。
ただ 10個もあるのは、ちょっと多すぎるような気はするけどね。

>>239
頼むから、もう少し勉強してからレスしてくれ。
全然俺の言ってることが理解できてないよ。
242デフォルトの名無しさん:2008/03/24(月) 00:08:40
で、アホなのはどっちなの?初心者なのでよく分かりません
243デフォルトの名無しさん:2008/03/24(月) 00:51:50
>>242
やり方は色々ある。って話に落ち着けていいんじゃないのw
メイヤーズもそんなことeffective c++に書いてたでしょ。
244デフォルトの名無しさん:2008/03/24(月) 05:56:56
>>242
「そいつの中にあるもの」の質はともかく、
「そいつの中にあるものを説明する能力」はどっこいどっこいです。
245デフォルトの名無しさん:2008/03/24(月) 17:47:39
仮想関数を持たないクラスXとクラスYがあります。
YはXを継承しています。これらのクラスに対応する
インターフェイスのクラスIXとIYを以下のように定義しました。
しかし、コンパイルエラーでした。クラスYは抽象クラス
とみなされたようです。でも、クラスYはf()の定義も
g()の定義も持っているので抽象クラスではないように思えます。

XとYのインターフェイスを作る方法を教えて下さい。

class IX {
virtual void f() = 0;
};

class X : public IX {
void f() {}
};

class IY : public IX {
virtual void g() = 0;
};

class Y : public X, public IY {
void g() {}
};

int main()
{
Y y; // エラー(抽象クラスあるいは構造体のオブジェクトが宣言されています)
return 0;
}
246デフォルトの名無しさん:2008/03/24(月) 17:54:22
 IX  IX
 ↑  ↑
  X  IY
  ↑↑
   Y

という継承木になっている。
X::IX::f は定義されているが、
IY::IX::f は定義されていない。

インタフェースクラスを作るなら、IX を仮想継承する必要がある。
ただ、それでも Y で f を定義する必要がある。

あと、インタフェースクラスに限らず、基底クラスには
必ず仮想デストラクタを定義するのを忘れないように。
247デフォルトの名無しさん:2008/03/24(月) 18:14:09
>>246
ありがとうございます。
以下のように変更したらエラーが警告になりました。
この警告は無視していいような気がします。

>あと、インタフェースクラスに限らず、基底クラスには
>必ず仮想デストラクタを定義するのを忘れないように。
OKです。

class IX {
virtual void f() = 0;
};

class X : virtual public IX {
void f() {}
};

class IY : virtual public IX {
virtual void g() = 0;
};

class Y : public X, public IY {
void g() {}
};

int main()
{
Y y; // 警告('Y' : 2 つ以上のメンバが同じ名前を持っています。'X::f' から継承します。)
return 0;
}
248デフォルトの名無しさん:2008/03/24(月) 18:50:40
Y::f では X::f と IY::f のどっちの実装を使えばいいのか分からないというもの。
まあ、今回の場合は IY::f に実装がないから X::f を使いますよという警告だけど、
Y に void f() { X::f(); } と書いておくのが無難。
249デフォルトの名無しさん:2008/03/24(月) 19:06:35
class T
{
 T( int );
}

T *T_array = new T [100];
は出来ないじゃん?
#placement new使えってのはなしで。

std::vectorはどうやってこういうコンストラクタが引数を持ってるクラスを受け入れてるの?
250デフォルトの名無しさん:2008/03/24(月) 19:07:20
placement newで
251デフォルトの名無しさん:2008/03/24(月) 19:11:33
>>248
上の例では void f() 1個だけですが、実際のIXは純粋仮想関数を
22個もっています。Yに22個の関数をわざわざ定義するのはなんだか
無駄な気がするのですが。。。
252デフォルトの名無しさん:2008/03/24(月) 19:18:29
>>251
まあ、面倒なら今のところは無視してもいいかもしれない。
コメントでも書いとこう。
253デフォルトの名無しさん:2008/03/24(月) 19:26:44
>>241
頼むから、もう少しまともな説明してくれ。
254デフォルトの名無しさん:2008/03/24(月) 19:31:33
>>252
わかりました。ありがとうございました。
255デフォルトの名無しさん:2008/03/24(月) 19:31:46
friend 使うと「一部のクラス」が増えるとManagerも弄らないと駄目だな。
256デフォルトの名無しさん:2008/03/24(月) 19:34:11
拡張性を敢えて犠牲にするなら、個別に friend するしかない。
拡張性もある程度考慮するなら基底クラス作ってそれだけ friend 。
あとは本人がどうしたいか、だな。
257デフォルトの名無しさん:2008/03/24(月) 20:12:41
>>253
非常に初歩的な内容だし、あの説明で理解できないなら、
もうあきらめた方がいいぞ。
258デフォルトの名無しさん:2008/03/24(月) 22:58:50
IDすら出ない板で煽り煽られ大変ですな
259180:2008/03/24(月) 23:04:33
私の為に喧嘩しないで><。
260デフォルトの名無しさん:2008/03/24(月) 23:59:31
struct B{
 struct P{ B *temp; }
 B( P p ){ swap( *this, *(p.temp) ); }
 operator P (){ P p; p.temp = this; return p; }
};

B Return(){ return B(); }
void Accept( B &b ){};

------------
Accept( Return() ); //Error



俺、何間違えてるの?
261デフォルトの名無しさん:2008/03/25(火) 00:06:50
設計?
262デフォルトの名無しさん:2008/03/25(火) 00:07:13
エラーメッセージはキチンと書く
263デフォルトの名無しさん:2008/03/25(火) 00:09:50
264デフォルトの名無しさん:2008/03/25(火) 00:11:00
質問の仕方
265デフォルトの名無しさん:2008/03/25(火) 00:11:54
266デフォルトの名無しさん:2008/03/25(火) 00:11:55
Bにデフォルトコンストラクタないからとか?
267デフォルトの名無しさん:2008/03/25(火) 01:12:43
Humanクラスを基底クラスとするTanakaやAsouやIshikawaクラスがあるとします
Humanは抽象クラスとして用いるつもりです
このときHumanにあるstaticメソッドを一回だけ呼び出したいときってどうすればいいでしょうか?
Humanのコンストラクタで呼び出したとすると、TanakaやAsouのコンストラクタでも呼び出されますよね
static bool initのような変数をフラグとして使う方法は思いついたのですが、
もっとスマートな方法はないのでしょうか?
268デフォルトの名無しさん:2008/03/25(火) 01:16:38
シングルトンやそれに関わるC++の実装は非常に面倒くさくて
自分で一からやろうと思うとどうしても乱雑になる。
マルチスレッドが入ってくるともっと面倒くさくなる。
269デフォルトの名無しさん:2008/03/25(火) 01:25:21
>>260
人生、かな?
270デフォルトの名無しさん:2008/03/25(火) 01:49:26
>>267
そのメソッドを呼び出したいのは、Human派生のオブジェクトを生成したタイミングなの?
271267:2008/03/25(火) 02:13:35
>>270
そうですね
Human派生のオブジェクトを生成する前に呼び出しても構わないのですが
272デフォルトの名無しさん:2008/03/25(火) 02:30:23
>>271
であれば、全てが始まる前に自分で一度だけ呼ぶのが良いと思うな。
273デフォルトの名無しさん:2008/03/25(火) 02:31:52
>>272
それはstaticな変数をフラグにするよりダメじゃねぇかw
274267:2008/03/25(火) 02:39:11
>>272
あぁそうか、そもそもstaticなメソッドなわけだから

int main(){
   Human::onlyOnceCalled()

みたいなかんじで
最初の方で適当に呼んでおくってのもありかもしれませんね
一回だけしか呼ばないって保証がないような気もしますが
275デフォルトの名無しさん:2008/03/25(火) 02:49:38
>>274
必ず最初に読んでしまってよいなら、クラスにスタティックなメンバを定義して
それの初期化の中で実行させてみては?

// human.h
class Human() {
 // 中略
 class Initializer { Initializer() { onlyOnceCalled(); } };
 static Initializer init;
};

// human.cpp
Human::Initializer Human::init;

文法間違ってたらすまん
276275:2008/03/25(火) 02:51:47
Human::Initializerのコンストラクタがpublicになってないとか、いろいろダメだorz
そこは適当におぎなって
277267:2008/03/25(火) 03:01:51
>>275
なるほど。こういう方法もあるんですね
勉強になりました
ありがとうございました
278デフォルトの名無しさん:2008/03/25(火) 03:05:20
保証が欲しかったのか。失礼。
initialization orderを気にするならこんな感じかな。
class Human() {
class Initializer {
Initializer() { onlyOnceCalled(); }
public:
static void Initialize() { static Initializer instance; }
};
};

これで、Initializer::Initializeを呼んだタイミングで一度だけ初期化されるようになるよ。ただしこの場合は複数スレッドとかが動き出す前に呼んでね。
279260:2008/03/25(火) 09:32:50
ぇ?コンパイル通る?
gccだと通らないんだけど・・・
280デフォルトの名無しさん:2008/03/25(火) 09:53:30
>>279
どこを見てそう思うんだよ・・・
指摘してくれてるだろ
>>263
>>266
あとAcceptがReturnの返す一時オブジェクトを参照してるから何とかしよう
281デフォルトの名無しさん:2008/03/25(火) 11:14:49
>>279
まずは省略や手抜きをせずに、Bの定義を全部書け。
そして何をしたいのかはっきりさせろ。
282260:2008/03/25(火) 16:02:29
いや、やりたいことは下のやつを知りたかっただけ。
http://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms/%E6%89%80%E6%9C%89%E6%A8%A9%E7%A7%BB%E5%8B%95%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF(Move_Constructor)
に書いてあることってnon-const referenceを受けるべきとろこに一時オブジェクトを渡せるって話だと思って、
渡してみたらコンパイラ通らないどーん。な状況。
283デフォルトの名無しさん:2008/03/25(火) 16:44:42
>>282
これで通った
struct B{
struct P{ B *temp; };
B(){}
B(P p){ swap( *this, *(p.temp) ); }
operator P () { P p; p.temp = this; return p; }
};
B Return(){ return B(); }
void Accept( B b ){};
int main(){ Accept( Return() ); }
284デフォルトの名無しさん:2008/03/25(火) 17:14:20
参照渡しから値渡しに変更した理由が分からん
285デフォルトの名無しさん:2008/03/25(火) 17:18:44
抽象クラスのメソッドの定義で質問があります
抽象クラスにおいて、自分自身のクラスへのポインタの引数を取るメソッドは不可能なのでしょうか?
たとえばこういうコードです
class Human {
  void foo(Human *human) = 0;
};

コンパイルエラーになってしまいますが、なぜそうなるのか分かりません
抽象クラスだから、インスタンスを作れないので
void (Human human);
のようなメソッドはだめですよね、でもポインタならいけると思うのですが
286デフォルトの名無しさん:2008/03/25(火) 17:20:52
B::operator P()の戻り値から構築されるBの一時オブジェクトは非const参照のAccept(B&)では受け取れないんじゃ?
287デフォルトの名無しさん:2008/03/25(火) 17:23:26
その発送は無かったわ、thisポインタというものが(ry
virtual書いてみたらどうかな?
288デフォルトの名無しさん:2008/03/25(火) 17:27:02
一時変数を値渡しする理由は?const参照にしない理由が分からない。
289285:2008/03/25(火) 17:32:20
>>287
すいません元のコードではvirtualをつけてました
thisポインタは分かるのですが、この抽象クラスを継承したクラスの間でやりとりしたいことがあるのです
不勉強なので間違ってるかもしれませんが、「関連」というのをやりたいのです。
>>285の例でやるなら、一般的にはHumanクラスにHuman *hoge;みたいなポインタをメンバに持たせて関連付けするそうですが
関数の引数でやれないかと思いまして
290デフォルトの名無しさん:2008/03/25(火) 17:35:09
>>288
const参照でもいいかもしれないけど、それ以上所有権を動かせなくならない?
291デフォルトの名無しさん:2008/03/25(火) 17:45:20
Acceptに入ってからも譲渡するなら、
void Accept(B& b) {}
B b = Return();
Accept(b);
の方が良くないかな、それ以前に何のためのPなんだ?
292デフォルトの名無しさん:2008/03/25(火) 17:47:47
>>285
どういう一般的例なのかちょっと分からないけど、
処理と情報を分ける実装の方が個人的にはスッキリするかな

んで、そのプログラムvirtualつけてエラーが出る理由が分からないんだけど…
293デフォルトの名無しさん:2008/03/25(火) 17:49:24
あぁ、失礼した、operator Pはconst守るようにしてるのね
ごめん、俺が悪かった
294292:2008/03/25(火) 18:06:34
>>292
すいませんすごく単純なクラスを作り直し、実験してみると、エラーはでませんでした。

「抽象クラスをインスタンス化することができません」というエラーメッセージだったので、
質問させていただいたのですが、おそらく他のところにエラー.の原因があると思うのでもう一度見直してみます
295294:2008/03/25(火) 18:09:51
>>294の名前欄は>>285の間違いです
296デフォルトの名無しさん:2008/03/25(火) 19:45:31
auto_ptrはauto_ptr_refクラスを介して対処している。
もう知っているかもしれないけど、
C++0xでは非const参照でも一時オブジェクトを受けられるようになる(右辺値参照)。
297デフォルトの名無しさん:2008/03/25(火) 22:07:18
move semantics と rvalue reference &&
298デフォルトの名無しさん:2008/03/25(火) 22:23:46
右辺値参照は何度もこのスレでも話されてるけど理解できん。
299デフォルトの名無しさん:2008/03/25(火) 22:33:41
エラー出る出る言うなら、同じエラーが出る小さいプログラムを示せよ。
BやらPやらの例も、そもそもswapがないでコンパイル止まるしな。
300デフォルトの名無しさん:2008/03/25(火) 22:34:02
右辺値及び左辺値(この二つは組)、参照の理解を固めてから見直すとよろし
301デフォルトの名無しさん:2008/03/25(火) 22:45:08
>>298
簡単に言うと「swapでおk」ってこと。
302260:2008/03/25(火) 23:08:35
おなにーでさーせん。swapとかごめん。あと別に必要なかったかも。
コンパイル通った。
>>283と一緒かな?

class D {
 public:
  struct Proxy { Proxy( D *d ):d_( d ){}; D *d_; };
  operator struct Proxy () { return Proxy( this ); };
  D( struct Proxy p ) {};
  void operator = ( struct Proxy p ){};
  D(){};
  D( D &rhs ){};
  void operator = ( D &rhs ){};
};

D Return() { return D(); }

int main( int, char** ){
D d = R();

return 0;
}

Accept( D &d );ってのは間違ってたかも。
ようは、
D( const D &rhs )だと、オーナーシップの移譲とかでrhsに変更加えられない。で、
D( D &rhs )だと、右辺値を渡せない。
だから、Proxyを返して、ごにょごにょする。って話なのか。
303デフォルトの名無しさん:2008/03/27(木) 00:31:14
Cの関数ポインタにC++のClassの実体化した関数ていれられますか?
ビルドエラーが出るんですけど、そもそもそんなの出来ない?
304デフォルトの名無しさん:2008/03/27(木) 00:54:49
>>303
できない。
関数ポインタとメンバ関数ポインタは別物。
305デフォルトの名無しさん:2008/03/27(木) 01:38:47
>>303
Windowsのコールバック関数みたいに
こっちから引数を渡せれば、どうにでもできる。
306デフォルトの名無しさん:2008/03/27(木) 01:54:41
>>303
sizeofを使ってポインタサイズを調べてみると、あれびっくりサイズがデカイって分るよ。
どうやっても入りません、キャストしたら情報ロストします。
307デフォルトの名無しさん:2008/03/27(木) 02:00:59
>>306
いろいろ勘違いしてるような。
308デフォルトの名無しさん:2008/03/27(木) 02:24:05
>>307
どこを?
具体的にどうぞ。
309デフォルトの名無しさん:2008/03/27(木) 02:29:53
>>304-306 のうち確実に間違っているのは >>305 です、要注意。
310デフォルトの名無しさん:2008/03/27(木) 02:49:53
面倒だからboost::functionを調べてみ >303
311デフォルトの名無しさん:2008/03/27(木) 02:56:20
詳しく説明した方がいいかと
要するに、メンバ関数ポインタがさす関数はvirtualである事もあって
インスタンスに仕込まれた仮想テーブルを参照して、関数テーブルのうちどの位置にあるものかを取得する必要がある。
また、関数はvirtualでないケースもある、この場合仮想テーブルには関数のアドレス情報はないので、関数メンバポインタ内に情報がなければならない。
関数メンバポインタはこれら複合情報で構成された構造体となっている。
312デフォルトの名無しさん:2008/03/27(木) 03:03:53
どこが詳しいのか
313デフォルトの名無しさん:2008/03/27(木) 06:03:12
それなりに詳しいと思うけど、
であるがゆえに「要するに」から始まっているのは間違いだと思う。
314デフォルトの名無しさん:2008/03/27(木) 07:26:14
>>303
関数ポインタには入れられないが、
実体とメンバ関数ポインタの対を構造体にしたものを引数に取る
ラッパ関数を通して呼ぶことはできる。
もちろん、C 側ではその構造体を直接扱うことはできないから、
void * を通すなり不完全型を利用してポインタで扱うなりする必要はあるけど。
315デフォルトの名無しさん:2008/03/27(木) 07:39:53
>>309
>>305はCのライブラリのコールバック使うときとかの対処法の話じゃね?
大抵はvoid*のパラメータ持ってるし。
316デフォルトの名無しさん:2008/03/27(木) 07:46:12
virtual関係無いよね。
317デフォルトの名無しさん:2008/03/27(木) 08:15:45
そもそも、C++のclassの実体化した関数って何?実体化って何を言ってるんだ
インスタンス増えたら関数も増えるとか思ってるのだろうか、理解に苦しむ

http://www.microsoft.com/japan/msdn/vs_previous/visualc/techmat/feature/jangrayhood/
318303:2008/03/27(木) 08:50:26
やりたいのは複数newしたクラスからCの関数叩くんですけどその時の引数にコールバック用のCの関数ポインタがあるんです
そしてその時呼んだ実体に関数ポインタによって帰ってくるようにしたいんです
319デフォルトの名無しさん:2008/03/27(木) 09:03:26
引数を加えて、static関数で良いんじゃ?
320デフォルトの名無しさん:2008/03/27(木) 09:20:50
>>317
非staticメンバ関数/インスタンスメソッドの事だとみんな理解してるよ。

>>318
コールバック関数のパラメタを汎用ポインタとかで指定できるなら、そこにオブジェクトのアドレスを入れて、コールバック関数内でキャストしてメンバ関数を呼ぶ。
パラメタを指定できないなら、コールバック関数から見えるスコープの変数にオブジェクトのアドレスを入れておき、コールバック関数からメンバ関数を呼ぶ。
321デフォルトの名無しさん:2008/03/27(木) 10:10:15
クラスの関数ポインタはthisが略されてるようなもんじゃね
322デフォルトの名無しさん:2008/03/27(木) 10:31:11
>>317
往生際が悪い、素直に自分の知識不足でしたと認めろ
323デフォルトの名無しさん:2008/03/27(木) 11:13:55
>>317
そのあたりは処理系依存だろ
324デフォルトの名無しさん:2008/03/27(木) 13:09:21
static メンバ関数を C のコールバックに登録するのってよく見るし実際に
やったこともあるんだけど、ほんとは extern "C" と extern "C++" の違いで
型が遭わないはずなんだよね。

だからって対応策がわかんないし、使ったことのあるコンパイラでは全部通るから
そのまま使っちゃうんだけどさ。
325デフォルトの名無しさん:2008/03/27(木) 13:35:22
>extern "C" と extern "C++"
"C" とかの修飾は、識別子を外部にどういう規則で公開するかという点についての指定であって、スタックフレームの作り方の指定ではない。
機種依存なので、そっちにいけと事になるが、cdeclとpascalが違えば "C" を付加しても動作しない。
C型のスタックフレームを持つ関数として登録可能な関数なら、C型のコールバックに登録する事ができるという事。
そうでないなら、コンパイルが通ったとしてもうまくいかない。
326デフォルトの名無しさん:2008/03/27(木) 13:52:21
>>325
スタックフレームとか実装に立ち入った話はしてない。言語概念上の型が違うんだよ。
327デフォルトの名無しさん:2008/03/27(木) 13:53:59
>>326
力いっぱいデタラメぶちかまさない
328デフォルトの名無しさん:2008/03/27(木) 13:58:42
知識不足は許容できるが嘘吐きになってはイカンぜよ
329デフォルトの名無しさん:2008/03/27(木) 14:03:56
>>327-328
気持ちはわかる。きっとみんなこれらは同じものとして使ってるだろうし、
動作も問題ないだろうさ。

でも規格ではエラーにならないとダメなんだよ。はっきり書いてあるから。

7.5 "Linkage specifications" p1 より
> ... Two function types with different language linkages are distinct types even
> if they are otherwise identical.

gcc でもバグ扱いだ。
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2316
330デフォルトの名無しさん:2008/03/27(木) 14:06:37
>>329
自分を嘘と虚栄で塗り固めるような真似はやめた方がいい、どこに突っ込み入っているのかすら理解できていないだろ。
331デフォルトの名無しさん:2008/03/27(木) 14:10:44
静的メンバ関数はextern "C++"ではない
332デフォルトの名無しさん:2008/03/27(木) 14:11:10
328は327に宛てたもんだと俺は思った、どうでもいいけど。
333329:2008/03/27(木) 14:11:40
>>330
ごめん。どこに突っ込み入っているのかすら理解できてない。
どこが嘘になってるの?
334デフォルトの名無しさん:2008/03/27(木) 14:16:32
>>331
何を根拠にそんなこと言うのか知らないけど、じゃぁ静的メンバ関数の
language linkage は "C++" 以外の何になるのさ?
335デフォルトの名無しさん:2008/03/27(木) 16:56:26
虚言癖というか妄想癖というか・・・なんかもう病気だね(汗
336デフォルトの名無しさん:2008/03/27(木) 17:04:34
>>334
静的メンバ関数のリンケージは内部リンケージで
その根拠は外部に公開されないから
逆にextern "C++"と同じという根拠は?
337デフォルトの名無しさん:2008/03/27(木) 17:05:02
もうv(^・^)vの人はいないの?
338デフォルトの名無しさん:2008/03/27(木) 17:20:53
ちゃんと勉強しろ、そんな高度な話題じゃねぇよ
339デフォルトの名無しさん:2008/03/27(木) 18:55:41
コンストラクタの中で
配列宣言しているオブジェクトの
コンストラクタ引数を設定するにはどうしたらいいですか?
340デフォルトの名無しさん:2008/03/27(木) 19:03:37
class Test{
Test0 objects[10];
...
};

Test::Test()
:objects[0]( 10 )
,objects[1]( 8 )
...
{
}

こんなかんじをやりたいのです。
もちろん、これではエラーです
341デフォルトの名無しさん:2008/03/27(木) 20:36:48
>>339
できないよ。
342デフォルトの名無しさん:2008/03/27(木) 20:51:07
解答を待っているのかもしれないが、本当にできないから。
http://www.geocities.jp/ky_webid/cpp/language/012.html
343デフォルトの名無しさん:2008/03/27(木) 20:57:51
どうしてもそれっぽいことがやりたいなら
vector<Test>にひとつひとつpush_back()するか
ポインタの配列にしてひとつひとつnewすればいいんでないの
344デフォルトの名無しさん:2008/03/27(木) 21:55:56
VC++6で
for(int i=0; i<10; i++){
...
}
for(int i=0; i<10; i++){
...
}
って書いたら
iの再定義っておこられた
拡張子cppになってるのに
345デフォルトの名無しさん:2008/03/27(木) 21:57:25
仕様です
346デフォルトの名無しさん:2008/03/27(木) 21:58:46
1998年発売のソフトやもん。
347デフォルトの名無しさん:2008/03/27(木) 21:59:23
>>344
びっくりするくらいみんな知ってる。
規格準拠していないんだから何も問題ない。
348デフォルトの名無しさん:2008/03/27(木) 22:01:35
>>344
#define for if(0); else for

魔法のおまじない
349デフォルトの名無しさん:2008/03/27(木) 22:01:59
当時は準拠してたんだよ
350デフォルトの名無しさん:2008/03/27(木) 22:03:21
まだ規格もなかったのに何に準拠してたというのか。
351デフォルトの名無しさん:2008/03/27(木) 22:04:00
常識。
352デフォルトの名無しさん:2008/03/27(木) 22:29:04
>324,329
だいたい、「関数ポインタ型」それ自体にはリンケージなんか無いだろ。
それともこーゆーコードが通るコンパイラでもあるのかっつーの。
typedef static void (*hoge)();
typedef extern void (*foo)();
typedef extern "C" void (*var)();
353デフォルトの名無しさん:2008/03/27(木) 22:36:23
typedef void (*__stdcall type)();

こういうのならたまにやる。
354デフォルトの名無しさん:2008/03/27(木) 22:36:46
それはリンケージじゃなくて呼び出し規約
355デフォルトの名無しさん:2008/03/27(木) 22:48:31
>>350
ARM、ISOのドラフト
356デフォルトの名無しさん:2008/03/27(木) 22:49:53
>>355
>>344 なていたらくでか
357デフォルトの名無しさん:2008/03/27(木) 22:58:27
>>356
forの中で定義した変数の有効範囲が
直後のループ本体に限られるようになったのは
結構遅かったのでは?D&Eでも軽く触れられていたし。

それに加え過去の互換性のためVC6はあれがデフォルトになったんだと思う。
358デフォルトの名無しさん:2008/03/27(木) 23:27:37
昔の人が考えた仕様には、頭おかしいだろうってのがそれなりに有るからね。
359デフォルトの名無しさん:2008/03/27(木) 23:47:27
初期のコンパイラの実装の都合もあったんじゃないかな?

最近のコンパイラで、forの変数の有効範囲が限られるようになってるのに最近気づいて思わずGJと叫んだ。
360デフォルトの名無しさん:2008/03/28(金) 00:10:34
>>357
まあ 1998 年と言えば規格が出る年だしな。
開発期間とか考えると多少前の仕様に準じようとしてたと考えるのが妥当だけど、
その時期ならドラフトとはいえかなりな部分まで練られてると思うんだけどな。
まあ、想像でしかないので本当にギリギリになって入れられた仕様なのかもしんないけど。

VC6 はテンプレートまわりがバグ持ちすぎてかなり酷いが、
テンプレートも遅くに入った仕様だからな・・・。
new がデフォで bad_alloc 投げないとか、とにかく色々と酷い上に、
しばらく次のコンパイラが出なかったという・・・。
361デフォルトの名無しさん:2008/03/28(金) 00:18:58
未だに古いライブラリとかで使わないといけないことが結構あるからねぇ
VS2005から入った俺としては結構苦痛
まあでもテンプレートさえなければインテリセンス反映が早いのはよい
362デフォルトの名無しさん:2008/03/28(金) 00:36:24
VC++6.0は当時の状況を考えればしょうがないと思う

問題なのは次のコンパイラがさっさと出なかった事
お陰で変に普及しちまって、このスレでもVC++6.0でコンパイルできません的な質問が絶えない
363デフォルトの名無しさん:2008/03/28(金) 00:38:12
全てはMSが次期製品を確実に買ってくれる為に図った陰謀。
364デフォルトの名無しさん:2008/03/28(金) 00:53:13
MSの事情的にはむしろ逆のような?
過去のシステムヘッダに, for で宣言した変数が
その後も生きることに依存したコードがあったっていう……
365デフォルトの名無しさん:2008/03/28(金) 00:56:00
#define for if(0) else for
のおまじないと使ったあとでATLをincludeすると
怒られるちゅーか
366デフォルトの名無しさん:2008/03/28(金) 01:14:53
>>363
そして満を持して登場した 2002 が糞だったという罠。
そして 2003 で大きく改善されるという二重の罠。
アカデミックだと無料アップグレードできないという三重の罠。
367デフォルトの名無しさん:2008/03/28(金) 01:16:50
#define for if(0); else for は色々やった後にやるとよろし。
368デフォルトの名無しさん:2008/03/28(金) 01:55:57
ってかincludeする前にundefするだろ・・・
369デフォルトの名無しさん:2008/03/28(金) 02:11:01
>>336,352
ややこしくて嫌になるが、内部とか外部とかがある「リンケージ」と
"C" とか "C++" とかがある「言語リンケージ」("language linkage") とは
別物。 >324,329 が言ってるのは言語リンケージのほうなんで、話がまるで
かみ合ってない。
370デフォルトの名無しさん:2008/03/28(金) 03:12:43
自信満々な>>336が可哀想に見えてきちゃったよw
逆にextern "C++"と同じという根拠は?ってのが哀愁をソソル
371デフォルトの名無しさん:2008/03/28(金) 03:26:11
>>336
素の「リンケージ」の話だとしてもおかしい。静的メンバ関数のリンケージは
ほとんど外部リンケージになる。例外は関数内のクラスのメンバの場合とかね。
372デフォルトの名無しさん:2008/03/28(金) 03:29:08
静的メンバ関数が「外部に公開されない」ってのもおかしいな。
クラスの宣言されたスコープや、クラス内での private なり public なりに
従うだろ、常考。
373デフォルトの名無しさん:2008/03/28(金) 03:50:38
びやーんはもうC++なんか使っていないらしい。
374デフォルトの名無しさん:2008/03/28(金) 05:40:45
ソースは?
375デフォルトの名無しさん:2008/03/28(金) 07:19:26
2ch
376デフォルトの名無しさん:2008/03/28(金) 08:03:31
>>372
public, privateと内部リンケージ, 外部リンケージはまた別の話だ
377デフォルトの名無しさん:2008/03/28(金) 08:07:53
もう何がなんだかわからないよママン
378デフォルトの名無しさん:2008/03/28(金) 09:26:26
>>359
もともとがCへのトランスレータだった事を考えれば自然に合点が行くね。
for( int i = 0 ; .... ) { ... }
変換後
{
 int i ;
 for( i = 0 ; .... ) { ... }
}
379デフォルトの名無しさん:2008/03/28(金) 09:47:14
>>377
C++の仕様書を見ればいいと思うお
380デフォルトの名無しさん:2008/03/28(金) 09:57:02
>>372
リンカなどの外部に公開され得るのはクラスであって内部リンケージであるメンバが同様に公開されているように見えるのは処理系の都合
381デフォルトの名無しさん:2008/03/28(金) 11:33:58
>>380
クラスが外部リンケージを持つときに、メンバ関数が外部リンケージを持つかどうか は処理系依存だと言っているのならそれは違うよ
382デフォルトの名無しさん:2008/03/29(土) 03:01:24
>>377 >329,324
383デフォルトの名無しさん:2008/03/30(日) 01:04:01
テンプレートをつかうと一気にコンパイル時間が10倍に?!
384デフォルトの名無しさん:2008/03/30(日) 01:07:31
385デフォルトの名無しさん:2008/03/30(日) 15:11:26
template使っても
型が1個と100個じゃ大違いだろ
386デフォルトの名無しさん:2008/03/30(日) 15:17:08
このテンプレいつの間にか一つのレスにまとめられてたのかw
387デフォルトの名無しさん:2008/03/30(日) 15:27:00
template <typename Questioner>
int IsCompileTimeBecomeLongerByUsingTemplate() {
return ENVIRONMENT_DEPENDENT;
}
388デフォルトの名無しさん:2008/03/30(日) 16:25:46
テンプレート無意味過ぎる
389デフォルトの名無しさん:2008/03/30(日) 16:28:21
>>388
質問者に応じて別の回答をするように特殊化するんだよ。
390デフォルトの名無しさん:2008/03/30(日) 16:36:16
template<> int IsCompileTimeBecomeLongerByUsingTemplate<教えて君>()
{
 throw spoon();
}
391デフォルトの名無しさん:2008/03/30(日) 16:59:30
匙は投げられた。
392デフォルトの名無しさん:2008/03/30(日) 17:30:09
the biggest news of the meeting was that we voted lambda functions and closures into C++0x.

// Writing a collection to cout, in C++0x:

for_each( w.begin(), w.end(),
[]( const Widget& w ) { cout << w << " "; } );
393デフォルトの名無しさん:2008/03/30(日) 17:59:38
スレ違い
394デフォルトの名無しさん:2008/03/31(月) 01:28:23
LRESULT CALLBACKの関数をCLASSに所属させるにはどうすればできますか?
395デフォルトの名無しさん:2008/03/31(月) 01:37:29
static
396デフォルトの名無しさん:2008/03/31(月) 02:07:44
397デフォルトの名無しさん:2008/03/31(月) 05:36:51
RTTIについて質問です。
RTTIありでオブジェクトファイルを生成したいが
外部libなどがRTTIを含んでいない場合は
自分側もそれにあわせてRTTIなしで組まなければ成らないのでしょうか?
398デフォルトの名無しさん:2008/03/31(月) 10:26:48
コンパイラオプションでRTTIを使うかどうかの設定の話なら、ケースバイケース。
自分が知るVC++では、外部のオブジェクトに対してtypeidやdynamic_castをしなければ、
自プログラムがRTTI有効でも、問題なくリンクして実行できる。
逆にそうでない処理系も世の中あるかもしれない。
399デフォルトの名無しさん:2008/03/31(月) 12:28:13
>>397
リンクでエラーが出たらオプション変えればいいんじゃないか?
400デフォルトの名無しさん:2008/03/31(月) 17:21:40 BE:1614463687-2BP(200)
http://www.borland.co.jp/cppbuilder/freecompiler/
が切れていてBorland C++ Compilerがダウンロードできないんだけど
401デフォルトの名無しさん:2008/03/31(月) 17:25:43
>>400
普通にアクセスできるしスレ違いですさようなら
402デフォルトの名無しさん:2008/04/01(火) 02:25:47
test
403397:2008/04/01(火) 02:34:57
>>398
環境依存てことですかね〜。

>>399
vcとのクロス開発あたりだとエラーがでてしまうのです;;

根本的になにをやりたいかというと、
シリアライズ機能を自前で実装しようと考えていまして
実装の際にRTTIのtypeidを利用して組むとらくそうなのですが・・・
ない場合はMFCやwxWidgetのようなクラス毎にマクロを仕組んで
独自の機構を作るしかないのかなって悩んでしまって・・
※boostのシリアライズという選択肢もありますが、boostが対応していない環境も考慮しました。
404デフォルトの名無しさん:2008/04/01(火) 06:49:14
というか、例外・RTTI・CRTは、何も考えずに
DLL超えとか、コンパイラ/オプションの違うlibを混ぜるとか
するとハマるよ?
405デフォルトの名無しさん:2008/04/01(火) 06:58:03
>>403
libのクラスをもう一度派生させたのを使ってみてはどうかな?
念のために聞くけど、そのlibをコンパイルしたコンパイラと使ってるコンパイラの種類とバージョンはあってる?
406397:2008/04/02(水) 04:43:48
>404
こちらはそこを懸念してるんですが、出来上がったものを使うのは私ではないのでなんとも・・・

>405
バージョンのほうはあってますが、こちらでつくったモジュールがどのようなケースで使用されるか
をすべて網羅するわけにはいかないので・・
派生というかstubのようなものをproxyとして使用する感じでしょうか?

なんというか、それなりの状況でも使用に耐えうるもの、となると
結局RTTIははずさなければならないのかな、と思いました。
407デフォルトの名無しさん:2008/04/02(水) 05:08:21
408デフォルトの名無しさん:2008/04/02(水) 06:12:08
アクセスできるすべての識別子をリストアップするようなツールはないでしょうか。
class X {
 int i;
public:
 int j;
 void f() {}
};
というような場合に、
X
X::j
X::f()
みたいに出力できるとうれしいのですが……。自分で字句解析するしかないかな。
409デフォルトの名無しさん:2008/04/02(水) 06:47:39
doxygenいろいろ設定すれば出来るんじゃね?知らないけど。
410デフォルトの名無しさん:2008/04/02(水) 08:45:55
>>407
他で散々話題になっているんだからここでまで張らなくていいよ。
411デフォルトの名無しさん:2008/04/03(木) 00:16:30
>>408
doxygenで可能。privateは出てこない(設定で変えられるかも)
412デフォルトの名無しさん:2008/04/05(土) 13:46:16
extern "C"しないで作られたshared libをcから呼ぶ方法ないでしょうか?
413デフォルトの名無しさん:2008/04/05(土) 14:19:43
マングリング名がCの識別子として使えるならいけるかもね
414デフォルトの名無しさん:2008/04/05(土) 14:49:22
C++ で C 用のラッパ関数作るといい。
415デフォルトの名無しさん:2008/04/05(土) 16:47:51
>>412
.defファイルをがんがって作る
416デフォルトの名無しさん:2008/04/05(土) 20:14:21
ふつーにdlopenするとか。呼び出し規約が同じとは限らないけどw
417デフォルトの名無しさん:2008/04/07(月) 17:03:38
gccxmlを使った他言語(pythonなど)への
インターフェース自動生成ツールが最近でてきてるけど
ちょっと複雑なコードだと自動生成に失敗するみたいだ

まだ発展途上のツールだから仕方ないのか
gccxmlに渡すオプションを考えればうまくいくのか

どうなんでしょうか?
418デフォルトの名無しさん:2008/04/07(月) 20:28:21
Exceptional C++ を読んでて、疑問点が出てきましたので質問します。
P173〜181 にかけての auto_ptr についての説明中に、

T* pt( new T(1) );
auto_ptr<T> pt( new T );
auto_ptr<T> a( source() );

↑どう見ても関数呼び出しに見えるのですが、
初期化子と解釈しないとどうも前後の説明から辻褄が合いません。
ですが、手元にある数冊の参考書を調べてもググってみても
以上のような構文は「コンストラクタ初期化リスト」以外には見あたりませんでした。
これは関数呼び出しなのでしょうか?それとも初期化子なのでしょうか?
もし、初期化子だとしたら、このような構文が出てきたときに
どのようにして見分けたら良いのでしょうか?
また、関数呼び出しのように見える初期化子の使い方についても
よろしくご教示願います。
419デフォルトの名無しさん:2008/04/07(月) 20:34:16
まさか<T>の部分を聞いてるのか?
420デフォルトの名無しさん:2008/04/07(月) 20:43:27
int i = 0;
int i(0);

上のふたつは等価、という話なのかな?

typename identifier(typename, typename, ...); // プロトタイプ宣言
typename identifier(arg1, arg2, ...); // 初期化
identifier(arg1, arg2, ...); // 関数呼び出し

ただし、C++では、関数宣言として解析できるものは関数宣言と見なすので、
list<int> data(istream_iterator<int>(cin), istream_iterator<int>());
は(cinの内容で初期化したlistの宣言ではなく)関数宣言になる。
421デフォルトの名無しさん:2008/04/07(月) 21:26:48
typedef typelist< char, 1, 2, 3, bool > LIST;
なんてことは出来ないですかね?
422デフォルトの名無しさん:2008/04/07(月) 21:32:31
boost::mpl, boost::tuple, boost::fusion辺り?
423デフォルトの名無しさん:2008/04/07(月) 22:43:42
>>418 読むだけじゃなくていろいろ試してみたら?
424デフォルトの名無しさん:2008/04/07(月) 23:49:20
classメンバを外部からリードオンリーに出来ませんか?
全部のメンバにゲッタを設定するのも面倒ですし
425デフォルトの名無しさん:2008/04/07(月) 23:49:20
>>418
その本持ってるが、その部分に間違いはない。
auto_ptrのメンバ関数のインターフェース見れば疑問は無くなるはず。
426デフォルトの名無しさん:2008/04/08(火) 00:19:52
>>424
面倒でも書く。
427デフォルトの名無しさん:2008/04/08(火) 00:32:34
>>424
class A{
public:
int aho;
};

const A baka; //全部リードオンリーなクラス
428デフォルトの名無しさん:2008/04/08(火) 00:46:55
>>424
必要になるまでゲッタなんて書かなきゃいい。
429デフォルトの名無しさん:2008/04/08(火) 00:59:50
>>424
constは?
430デフォルトの名無しさん:2008/04/08(火) 01:07:46
constなんてダサい。時代はreadonly。
431デフォルトの名無しさん:2008/04/08(火) 01:08:06
extern "C" {
struct B : public A
{};

}
ができた. class AのデータだけにはCからアクセスできるのかも
methodは無理か?
432デフォルトの名無しさん:2008/04/08(火) 01:25:03
extern "C" は変数と関数にしか意味がないからな。
433デフォルトの名無しさん:2008/04/08(火) 08:03:03
>>424
class A {
int member_prv;
public:
const int & member;
A() : member(member_prv) {}
}

まあ何だ、C++にはReadOnlyなプロパティを書く構文的な補助がないから、素直にgetter書いとけ。
434デフォルトの名無しさん:2008/04/08(火) 12:05:30
漏れはこんなマクロを書いた。

#define readonly(TYPE, ID)\
  public: TYPE ID() const { return _##ID; }\
  private: TYPE _##ID

class C {
  readonly(int, priv);
  readonly(unsigned int, b1) : 16;
  readonly(unsigned int, b2) : 16;
public:
  C() {}
};
435デフォルトの名無しさん:2008/04/08(火) 17:57:59
キーワードtypenameの意味が分かりません。テンプレートを定義するときに
よく使われるようですが、なくても良いような気がします。例えば、
プログラミング言語C++のp.599にある bind2nd の定義のtypenameを取って
コンパイルしてみましたが、コンパイルが通って、テストコードがきちんと
動きました。typenameの存在意義を教えていただけないでしょうか。
こういう場合にtypenameがなければ困るという分かりやすい例が欲しいです。

// ----- プログラミング言語C++(p.599)より -----
template <class BinOp>
class my_binder2nd : public unary_function<BinOp::first_argument_type, BinOp::result_type> { // my_を付けて実験
protected:
BinOp op;
typename BinOp::second_argument_type arg2; // このtypenameを取ってみた。
public:
my_binder2nd(const BinOp& x, const typename BinOp::second_argument_type& v) // このtypenameも取った。
: op(x), arg2(v) {}
result_type operator()(const argument_type& x) const { return op(x, arg2); }
};

template<class BinOp, class T> my_binder2nd<BinOp> my_bind2nd(const BinOp& op, const T& v)
{
return my_binder2nd<BinOp>(op, v);
436デフォルトの名無しさん:2008/04/08(火) 18:30:35
437デフォルトの名無しさん:2008/04/08(火) 18:33:46
C++FAQにありそうなネタだな
438デフォルトの名無しさん:2008/04/08(火) 22:18:03
コンパイラの迷いを断ち切るためにあります
439デフォルトの名無しさん:2008/04/09(水) 04:22:44
>>436
なるほど、理解できました。でもコンパイラが十分賢ければtypenameは不要だと
言えそうですね。コンパイラはテンプレートの解析時においては typename
を付けていない T::something が型かどうか分かりませんが、実際にコードを
生成するときには分かるので、本質的には曖昧さの問題はないように思えます。
440デフォルトの名無しさん:2008/04/09(水) 08:02:13
移植性を考慮するなら付けておけばいい。
441デフォルトの名無しさん:2008/04/09(水) 15:23:39
別のファイルで定義した変数を使うにはどうしたらいいんでしょう?
プログラムの改変を行っているのですが、前任者が作業ごとにファイルをわけています。
AAA.cppみたいなのがいっぱいあります。ヘッダファイルも同じ名前でたくさんあります。
442デフォルトの名無しさん:2008/04/09(水) 16:03:35
ググって一番上に来たサイト。
http://7ujm.net/C++/extern.html

内容は見てない。
443デフォルトの名無しさん:2008/04/09(水) 18:11:09
VC++ってもうやばくないですか?
今やVBC#でもms単位で計測しないと実行速度違いがわからないぐらいですし
出来ないこともないですよね
444デフォルトの名無しさん:2008/04/09(水) 18:34:02
>>443
場合によりけり
あと、その話題はこのスレ向きじゃない
445デフォルトの名無しさん:2008/04/09(水) 18:54:39
>>443
んな事ないよ
OpenGL Viewerが前回のバージョンから恐らくC#になったんだと
思うが、やはり動作がもさもさする。
446デフォルトの名無しさん:2008/04/09(水) 19:32:09
>>443
ゲームとかms単位が命取り
ms以下単位だったら考えてやる
447デフォルトの名無しさん:2008/04/09(水) 19:34:04
μに縮まったとしてもまだでかいだろ。
448デフォルトの名無しさん:2008/04/09(水) 19:42:54
数値計算とかやったことないんだろうなあ。
449デフォルトの名無しさん:2008/04/09(水) 19:48:47
>>441
そういうファイル構成はC++では一般的。
その同名のヘッダーを読み込みば、十分アクセスできるはず。その前任者のソースをよく読んでC++を勉強すること。
C++はexternを滅多に使わないからね。


450デフォルトの名無しさん:2008/04/09(水) 19:55:45
XBOX360のゲームは全部C#で書かれてるだろ
451デフォルトの名無しさん:2008/04/09(水) 19:57:04
>>443
全然やばくない。世界はもっと広い。
452デフォルトの名無しさん:2008/04/09(水) 20:26:56
>>439
T::something が型でも値でもコンパイルできてしまう場合は困るでしょう?
多分どちらかは間違っているんだから
453デフォルトの名無しさん:2008/04/09(水) 21:06:55
>>450
んなわけないだろ

プロがXNAで開発してるとでも思ってるのか?
454デフォルトの名無しさん:2008/04/09(水) 21:56:02
思ったw
455デフォルトの名無しさん:2008/04/09(水) 22:26:41
.netフレームワークを要求する商用アプリで動きが機敏なアプリをいまだかつて見たことないな。
456デフォルトの名無しさん:2008/04/09(水) 23:32:25
多言語からc++を呼ぶインターフェイスで
std::cout
がおかしくなる原因になってるらしくなんとかしたい
#define __streambuf なにか
にできればいいのだけど voidに置き換えるとコンパイルとおらない
何か適当なクラスでもないでしょうか?

457デフォルトの名無しさん:2008/04/09(水) 23:38:17
ios::sync_with_stdio で解決されるような問題じゃなくて?
458456:2008/04/10(木) 00:12:16
他言語の処理系がstdcoutをすでにリンクしているのに
さらにその処理系から呼び出すcのプログラム中でもリンクしてるのが
問題なってる可能性があるような気がしています

なので
#define __streambuf Hoge
できると多分うまくいくのではないかと
459デフォルトの名無しさん:2008/04/10(木) 00:17:47
XNAなめんな
460デフォルトの名無しさん:2008/04/10(木) 00:22:13
>>456
多言語から呼び出すってっ、もしかすると他言語からDLL呼び出しすることってことかな?
だったらライブラリの初期化がうまく言ってないんじゃないか?dllmainはこねこねした?
461デフォルトの名無しさん:2008/04/10(木) 00:23:42
あと、DLLはマルチスレッドライブラリでコンパイルだよ。
462456:2008/04/10(木) 00:24:19
>>460
正確にはlibhoge.soを呼んでます
libhoge.soがstd::stream関係をリンクしてます
463460:2008/04/10(木) 00:27:49
linuxでしたか。>>460はwinの場合の注意事項でした。
464デフォルトの名無しさん:2008/04/10(木) 07:50:43
>>461
MTでコンパイルしないといけない決まりでもあるの?
465デフォルトの名無しさん:2008/04/10(木) 08:21:08
>>464
ある。
DLLをコンパイルするときはMTでする必要がある。プロジェクトの作成でDLLを選択すると自動的にマルチスレッドランタイムライブラリが選択される。
呼ぶ側はどっちでもいい。
466デフォルトの名無しさん:2008/04/10(木) 11:49:02
>>465
何の処理系の話か知らないがVisualC++なら
シングルスレッドのランタイムの静的ライブラリをリンクしたシングルスレッド専用のDLLを普通に作れる
467デフォルトの名無しさん:2008/04/10(木) 11:57:21
端で見てて想像した通りの食い違い方w
468デフォルトの名無しさん:2008/04/10(木) 12:10:14
初歩的な質問で申し訳ないんだが、他言語から C++ の
ライブラリを使って問題無いはず、という保証はあるんだろうか?

あと、普通に C++ で呼び出すとかなぜしないのだろうか。
(これは状況がわからんとなんとも言えないけど)
469デフォルトの名無しさん:2008/04/10(木) 14:18:03
operator==() の定義はクラスの中とクラスの外に置けますがどのように
使い分けるのでしょうか?

std::type_info はクラスの中でその他はクラスの外が多いのですが。
470デフォルトの名無しさん:2008/04/10(木) 15:34:04
別にoperator==()に限らずメンバ関数は中にも外にも置けるけど。
471デフォルトの名無しさん:2008/04/10(木) 17:04:36
ププ
472デフォルトの名無しさん:2008/04/10(木) 17:05:09
ペペ
473デフォルトの名無しさん:2008/04/10(木) 17:30:44
== どうするかは状況によるんでは。無理無く member にしないで
いいならそうすればいいような気がするが。中身の情報が必要な
場合に member にしてるんじゃないの?普通に生じる状況だと思うけど。
474デフォルトの名無しさん:2008/04/10(木) 17:43:05
メンバに出来るものは中に書く。
メンバに出来ないものは外に書く。
以上。
475デフォルトの名無しさん:2008/04/10(木) 18:05:52
c++のエラー出力の文字コードがutf-8になっているのですが、
euc-jpにする方法ありますか?
Linuxのeuc-jp環境でプログラミング行っており、
gcc version 4.1.2 です。
476デフォルトの名無しさん:2008/04/10(木) 18:18:07
iconv
477デフォルトの名無しさん:2008/04/10(木) 18:40:50
ロケール切り替えろとしか
478デフォルトの名無しさん:2008/04/10(木) 19:06:32
public 関数だけで実装できる場合は非メンバーにする。
friend を使って非メンバーにすることもある。
479デフォルトの名無しさん:2008/04/10(木) 20:50:36
式の対称性が必要なら非メンバー
480デフォルトの名無しさん:2008/04/10(木) 20:59:53
自身への参照を返すことが期待されるか、自身を変更する場合は、メンバーにすることが漏れは多いな。
operator=, +=等はメンバに。operator==, <<, +等は非メンバ(場合によってはfriend)にしてる。
481デフォルトの名無しさん:2008/04/10(木) 21:08:54
op == あたりの話はeffective C++に書いてなかった?
もう忘れちゃったけど。
グローバルにop ==を置くことでカプセル化が上がるとか
その話とはまた別?
482デフォルトの名無しさん:2008/04/10(木) 21:20:10
friend はできれば避けた方が良いというの無かったっけ?
483デフォルトの名無しさん:2008/04/10(木) 22:12:02
C++ Coding Standards の 44 には
「できるだけ非メンバーかつ非 friend の関数を書くようにしよう」
というのがありました。
484デフォルトの名無しさん:2008/04/10(木) 22:19:02
C++の本質はやっぱプリプロセッサとテンプレートだろ・・・
オブジェクト指向なんてうんこ
485デフォルトの名無しさん:2008/04/10(木) 23:00:41
プリプロセッサはちょっと違うだろ・・・
現実的にメタプログラミングするのには必要だけど。
個人的にはデストラクタを推すね。

2行目は同意。
486デフォルトの名無しさん:2008/04/10(木) 23:08:04
デストラクタとはいいところをつくね。
RAII 万歳!
487デフォルトの名無しさん:2008/04/10(木) 23:25:35
friendかな
488デフォルトの名無しさん:2008/04/10(木) 23:58:56
>>485 == >>486 ??
489デフォルトの名無しさん:2008/04/11(金) 00:01:31
デストラクタの価値が分からないうちは
プログラマの資格なしだぜ
490485:2008/04/11(金) 00:03:01
>>488
ID出ない板だからどうしようも無いけど、
違うとだけ。
491デフォルトの名無しさん:2008/04/11(金) 00:14:49
デストラクタはクリティカルセクション解除するのに使ってる。
メモリリークどころの騒ぎじゃない
492デフォルトの名無しさん:2008/04/11(金) 00:17:31
Javaとかどーやってんだ?
デストラクタ
493デフォルトの名無しさん:2008/04/11(金) 00:20:23
Javaはcloseとかdisposeとかメソッド作って
呼び出さないといけないんじゃなかったっけ?
494デフォルトの名無しさん:2008/04/11(金) 00:25:56
Javaはデストラクタ勝手に作ってくれるから。
DB接続とかファイルハンドルにクリティカルセクションだの
なんでも閉じてくれる。
495デフォルトの名無しさん:2008/04/11(金) 00:28:48
前スレから
http://pc11.2ch.net/test/read.cgi/tech/1200044614/496-

496 :デフォルトの名無しさん [sage] :2008/02/15(金) 14:44:30
  つまるところc++ではデストラクタに頼るべき。

497 :デフォルトの名無しさん [sage] :2008/02/15(金) 14:54:04
  C++はつまるところデストラクタのことだからな
  closeさせといてガベージコレクタがあるとか抜かす言語は笑えるな
  intは回収できるが巨大なファイルリソースはリークするわけだ

498 :デフォルトの名無しさん [sage] :2008/02/15(金) 15:06:22
  日本語でおk

499 :デフォルトの名無しさん [sage] :2008/02/15(金) 15:08:34
  >closeさせといてガベージコレクタがあるとか
  禿げあがる程同意。
  
  C#はusing(o1,o2,...){}があるから多少マシだけど、
  forみたいにusing用のスコープ作るから
  スコープ違いが混じるとネストして見辛くなる。
  どう考えてもc++みたいに対象の変数のスコープでDisposeした方が良いと思う。
  
  javaのtry-finally-closeに至っては論外。
  しかもcloseで例外出たらfinally内で潰さないと
  try内で発生したより重要な例外が消されるし・・・。

500 :デフォルトの名無しさん [sage] :2008/02/15(金) 16:33:04
  >どう考えてもc++みたいに対象の変数のスコープでDisposeした方が良いと思う。
  そして言語はC++/CLIへと進化するのであった、まる
496デフォルトの名無しさん:2008/04/11(金) 00:34:08
Javaをはじめ、メジャーな言語のGCはメモリ不足しか認識しないから、
明示的にcloseしない場合、メモリに余裕があればfinalizeは呼ばれず、
DB接続も閉じられない

そしてコネクションプールのタイムアウトで死に始める業務アプリ
鳴り始めるサポートデスクの電話機達
497デフォルトの名無しさん:2008/04/11(金) 00:39:21
まぁJavaなんてマーケット戦略で広まっただけのうんこ言語だからな・・・
プログラマと名乗るくらいならC++くらいできる頭を持って欲しい・・
498デフォルトの名無しさん:2008/04/11(金) 00:59:54
finalize()でリソース解放なんて保険でしかないからな
499デフォルトの名無しさん:2008/04/11(金) 01:00:32
リソース管理で似た話を読んだことある気がしてたけど思い出せた
ttp://mag.autumn.org/Content.modf?id=20050506023118
500デフォルトの名無しさん:2008/04/11(金) 01:00:40
でもね、C++は巨大で複雑怪奇だからね。Cを引きずってる面もあるし。
無駄を削ぎ落として細部を明確にした言語が望まれるというのもわかるよ。
それとGCの有用性とは別の話だが。
501デフォルトの名無しさん:2008/04/11(金) 01:03:52
実はVBなんかも
リソース周りは優秀だったりする
502デフォルトの名無しさん:2008/04/11(金) 01:26:11
continuationを明示的に扱えない言語はうんこ
503デフォルトの名無しさん:2008/04/11(金) 01:26:35
scheme習いたてですか?
504デフォルトの名無しさん:2008/04/11(金) 01:55:30
>>503
C++習いたてです。
505デフォルトの名無しさん:2008/04/11(金) 07:46:34
C#のusingの使いづらさは異常
scopedとでもして識別子が入ってるブロックの最後でdisposeしてくれたほうがよかった
506デフォルトの名無しさん:2008/04/11(金) 08:50:00
素朴な疑問です。

#include <iostream>
struct S { virtual void hoge() = 0; // 純粋仮想のみ };
struct S1 : public S { void hoge() { std::cout << "S1" << std::endl; }};
struct S2 : public S { void hoge() { std::cout << "S2" << std::endl; }};
int main()
{
 S1 s1;
 S2 s2;
 S& r1 = s1;
 S& r2 = s2;
 r1.hoge();
 r2.hoge();
 r1 = r2; // 基本クラスの参照を代入
 r1.hoge();
 r2.hoge();
 return 0;
}

VC8で上記のコードを実行すると
S1
S2
S1
S2
と表示されました。
r1 = r2;はS::operator=を呼ぶだけなので何も変わらない、と理解したのですが、
これはC++的に正しい挙動なのでしょうか?
それとも未定義でたまたまこうなっているだけなのでしょうか?
507デフォルトの名無しさん:2008/04/11(金) 08:55:40
あ、改行を削ったらコメントをミスりました。
> struct S { virtual void hoge() = 0; // 純粋仮想のみ };

> struct S { virtual void hoge() = 0; /* 純粋仮想のみ */ };
です。
508デフォルトの名無しさん:2008/04/11(金) 08:56:43
単純に、自動生成されたoperator=(S, S)で仮想関数テーブルが書き換わらないようになってるだけ。
509デフォルトの名無しさん:2008/04/11(金) 08:57:18
s1, s2のうちSの部分だけがコピーされた、と解釈すればわからんでもない
510デフォルトの名無しさん:2008/04/11(金) 09:00:15
とりあえず解決するには自分でS2 operator=(S, S)を定義すればいいように思えるが、
それはS = Sの一般的な代入に関して考えるとかなり狂っているから諦めろって言う話でっていう
511デフォルトの名無しさん:2008/04/11(金) 12:27:47
>>498
同意。finalizeって呼ばれるとは限らないとか。ほんとに気休め程度だね。
512デフォルトの名無しさん:2008/04/11(金) 13:29:20
>>506
代入や他オブジェクトでの初期化でvptrは変更されない。
513デフォルトの名無しさん:2008/04/11(金) 15:56:17
class A { friend class B; int x; };
class B { class C {}; };

VC8.0 では class C から class A の x が参照できますがこれは C++ の仕様ですか?
514デフォルトの名無しさん:2008/04/11(金) 19:00:01
Cのreadableなプログラムを自動生成するメタ言語みたいなの
ないでしょうか?
readableじゃないのならあるのですが、読めないと意味ないのです
515デフォルトの名無しさん:2008/04/12(土) 16:01:17
具体例を。
516デフォルトの名無しさん:2008/04/12(土) 16:08:22
まともなCソースも >>514 には、readable じゃなさそうだ...。
517デフォルトの名無しさん:2008/04/13(日) 23:17:27
vector<int>で何個か反復子を進めたあと、
それが今何番目の要素なのかを知る関数はないですか?
518デフォルトの名無しさん:2008/04/13(日) 23:20:51
>>517
std::distance
519デフォルトの名無しさん:2008/04/13(日) 23:21:19
i - v.begin();
520デフォルトの名無しさん:2008/04/13(日) 23:55:08
できました、ありがとうございます。
521デフォルトの名無しさん:2008/04/14(月) 01:34:09
http://mag.autumn.org/Content.modf?id=20050506145337
ここ読むとC++よりもJAVAのほうがリソース管理に関して
優れているように思えるんだけど
522デフォルトの名無しさん:2008/04/14(月) 01:42:17
だから何だよ
523デフォルトの名無しさん:2008/04/14(月) 01:46:30
優れているというかパフォーマンスを犠牲にしてリソース管理の安全性を高めたという方が近いかな。
そんな事いったらC++も保守性を犠牲にパフォーマンスを高める余地のある言語と言えるけど。
ただJavaの場合は“余地”どころかプログラマに選択をさせない完全な“切捨て”であるけどね。
だからプログラマが手段を選択できる余地の残っているC++の方が優れている。終了。
524デフォルトの名無しさん:2008/04/14(月) 01:49:22
手段を選択する必要のある場面においては、だけどな。
525デフォルトの名無しさん:2008/04/14(月) 02:15:33
javaってfinallyの書き方間違えると死ねるしなあ
という話が >>495 にあるよ

jdbcでoracle使ったことがある人は知ってると思うけど、
closeし損ねるとリークしてそのうち動かなくなるんだよね

これを注意深く追ってると、「なんだかCでやってんのと変わらんなあ」
と思うぜ、実際。
526デフォルトの名無しさん:2008/04/14(月) 02:27:32
だってメモリしか管理してくれないもの
527デフォルトの名無しさん:2008/04/14(月) 07:08:37
>521
「RAIIが発明されるまでのC++」については、Javaのほうが
リソース管理が優れていた、と云わざるを得ない、けどねぇ。
528デフォルトの名無しさん:2008/04/14(月) 07:25:04
他のリソースも管理してくれればいいのになあ。
ファイルハンドルが足りない時には
ファイルクラスのインスタンスへのガベコレを
優先的にやってくれるとか。
529デフォルトの名無しさん:2008/04/14(月) 10:47:50
>>527
> 「RAIIが発明されるまでのC++」

って具体的に何を指すの? RAII ってプログラミング
ポリシーだと思うんだけど。「発明」されたっていまいちピンと来ない。

530デフォルトの名無しさん:2008/04/14(月) 11:04:02
RAII が浸透してない C++ って感じのことを言いたいんじゃないか?
未だに RAII を取り入れない C++ があるとは信じられないのかもしれないが。
531デフォルトの名無しさん:2008/04/14(月) 12:21:55
>>528
デストラクタを活用するべき
532デフォルトの名無しさん:2008/04/14(月) 12:25:18
javaの話だろ
533デフォルトの名無しさん:2008/04/14(月) 12:50:09
>>527
C with class の話ですか?
C++は初期のARMがかかれた頃から散々言われていますけど。
534デフォルトの名無しさん:2008/04/14(月) 18:05:47
>>529
強いて言えば、テンプレートがなかった頃には、
auto_ptrや(削除子付きの)boost::shared_ptrのような
汎用的なものは作りづらかったと思う。

それでも、fstreamみたいに個別に作っていく手があったはずだけど。
535デフォルトの名無しさん:2008/04/14(月) 21:38:58
なんでそこで糞設計のstreamを持ち出すかなー
536デフォルトの名無しさん:2008/04/14(月) 22:33:50
とりあえずデストラクタでcloseしてくれるからいいだろ。
今は糞設計かどうかなんて関係ない。
537デフォルトの名無しさん:2008/04/14(月) 23:13:37
自分のクラスにiteratorをアタッチ
するにはどうすればよいの?
538デフォルトの名無しさん:2008/04/15(火) 00:45:20
>>537
クラスって新しい container 作ってんの?
普通に vector とかにオブジェクト入れて iterator 使うとかいう話
じゃないんだよね?
539デフォルトの名無しさん:2008/04/15(火) 02:36:34
>>537 アタッチの意味がわからん。
540デフォルトの名無しさん:2008/04/15(火) 07:56:33
Rubyみたいにアタッチしたいんだけど
なんでできないの?
541デフォルトの名無しさん:2008/04/15(火) 08:59:06
だからアタッチって何だよ
542デフォルトの名無しさん:2008/04/15(火) 09:20:53
ウラララララーって叫ぶやつじゃね?
543デフォルトの名無しさん:2008/04/15(火) 16:55:57
それは、アパッチ
544デフォルトの名無しさん:2008/04/15(火) 16:56:46
>>543
叫ぶやつはジェロニモだ
545デフォルトの名無しさん:2008/04/15(火) 17:24:27
だってオラは人間だから
546デフォルトの名無しさん:2008/04/15(火) 21:52:48
テンプレートクラスとクラステンプレートの違いを教えてエロい人!!
547デフォルトの名無しさん:2008/04/15(火) 21:58:18
クラステンプレートを使って作られたクラスがテンプレートクラス
548デフォルトの名無しさん:2008/04/15(火) 22:09:23
何か詳しく書かれたサイトがあれば貼っていただきたいです。
549デフォルトの名無しさん:2008/04/15(火) 22:14:51
お前誰だよ
550デフォルトの名無しさん:2008/04/15(火) 22:20:43
つーか言葉にこだわってどーすんの
テンプレート勉強すりゃわかることだろうに
551デフォルトの名無しさん:2008/04/15(火) 22:32:59
ヒントがあれば十分だろ。
自分で考えて解決する楽しさを知らないやつは(ry
552551:2008/04/15(火) 22:33:53
>>551
誤爆しました。ごめんなさい、
553デフォルトの名無しさん:2008/04/15(火) 22:36:31
輪講で必要なんです。
わかりにくかったので聞いてみました。
554デフォルトの名無しさん:2008/04/15(火) 22:43:22
>>552
流れとしてはわりと的を射ている気がするw
555デフォルトの名無しさん:2008/04/15(火) 23:01:58
テンプレートクラスはただの間違いだと思う
クラステンプレートが正しい。だってあれはテンプレートだから

クラステンプレートをテンプレートクラスというのは
鉄パイプをパイプ鉄というようなもの
556デフォルトの名無しさん:2008/04/15(火) 23:16:18
>>555さん
わかりやすい表現ありがとうございます。

教科書には
クラステンプレートはテンプレートクラスから導出できる。
クラステンプレートは非テンプレートクラスから導出できる。
テンプレートクラスはクラステンプレートから導出できる。
非テンプレートクラスはクラステンプレートから導出できる。
と書いてあるのですが・・・
557デフォルトの名無しさん:2008/04/15(火) 23:24:08
まずは本の名前を晒してみれ。
558デフォルトの名無しさん:2008/04/15(火) 23:25:34
なんの哲学書だよw
559デフォルトの名無しさん:2008/04/15(火) 23:26:56
こんにゃくゼリーに使うこんにゃくをゼリーこんにゃくって呼んでる類だろ。
560デフォルトの名無しさん:2008/04/15(火) 23:26:59
ぐぐってでてきた。これは比較的納得できるかんじ
http://www.ed.kuki.tus.ac.jp/cgi-bin/vahwebx.exe/Ja_JP/cforaix/Extract/0/glossary/czgt.htm
クラス・テンプレート(class template)
暗黙的にまたは明示的にインスタンスを生成されるか、または特殊化されると、クラス型を作成するテンプレート。

テンプレート・クラス(template class)
クラス・テンプレート(class template)によって生成されるクラス・インスタンス。
561デフォルトの名無しさん:2008/04/16(水) 00:01:31
ソースで出てくる順がtemplate classだから間違えやすいな
562デフォルトの名無しさん:2008/04/16(水) 00:03:46
typename
563デフォルトの名無しさん:2008/04/16(水) 00:49:24
STLに
boost::any相当のものってないよね?

困った困った
564デフォルトの名無しさん:2008/04/16(水) 01:41:23
普通にboost::any使ったら?
565デフォルトの名無しさん:2008/04/16(水) 01:51:09
vectorにデータを追加した時にメモリ確保に失敗した場合、検出する方法ってありませんか?
newでいうbad_allocの例外をキャッチするような感じ。
566565:2008/04/16(水) 02:26:50
解決しました。orz
bad_alloc使えた...
567デフォルトの名無しさん:2008/04/16(水) 03:21:12
>>563
無いなら作れば?
大したもんでもないっしょ。
568デフォルトの名無しさん:2008/04/16(水) 13:24:51
あるアクションゲームをCとC++両方で作りました。
プレイする上で、まったく同じ動作をするものです。

Cでは主に構造体で、C++ではVectorで管理していました。
C++で作ったほうがプログラム実行時のメモリ消費量が多いのですが、
そんなもんでしょうか?
569デフォルトの名無しさん:2008/04/16(水) 13:41:18
そんなもん
完全に同一ソースでもバイナリレベルでは例外処理が入ったり、実行時型判定が入ったりする
570デフォルトの名無しさん:2008/04/16(水) 13:42:03
>>568
Vector は std::vector のこと?
そうなると構造体と std::vector とでは役割が違うので、置き換えれるわけ無いんだけど。

・・・もしかして
struct S { int a, b, c } s;
s.a = s.b + s.c;
これを
std::vector<int> s(3);
s[0] = s[1] + s[2];
にしたってこと?

まぁプログラムが違うんならメモリ消費量が違うのはあたりまえなんで、
あんまり気にしてもしょうがないと思う。同じになるはずっていう根拠でもなければ。
571デフォルトの名無しさん:2008/04/16(水) 13:49:57
配列のことを構造体といい間違えたのではないか。
572568:2008/04/16(水) 14:33:50
配列ですね、すみません。
消費メモリが数十MByte単位で変わってくると、さすがに気になったので質問しました。
C++の設計に改善点がまだあるような気もします。
573デフォルトの名無しさん:2008/04/16(水) 16:51:23
数十MBって、それってC/C++以前にプログラムの構造がおかしいだろ常考
574デフォルトの名無しさん:2008/04/16(水) 17:15:02
> C++で作ったほうがプログラム実行時のメモリ消費量が多いのですが、
これだけ読んだら、普通はもうちょっとささやかな差を想像するよね。
その想像をベースにして皆が一般的なことを回答したところで、いきなり
> 消費メモリが数十MByte単位で変わってくると、
っていう、量に関する新情報を出すっていうのは、広義の「情報小出し質問」だと思うよ。

自分だけが知っている状況を他人に説明するときは、発信する前に
「相手はこの説明に触れて、真っ先にどんなものを想像するだろうか?」
っていう思考を巡らせるべき。

で回答だけど、「構造体とvector」以外に両者のソースがどう違ってるかがわからないと、何とも言えない。
質問文に登場した要素だけで考えるなら、STLの使い方をどこかで根本的に間違えているんじゃないか
って気がするけども。
575デフォルトの名無しさん:2008/04/16(水) 18:22:21
前方反復子のクラスはデフォルトコンストラクタが必要ですけど、
デフォルトコンストラクタで生成した反復子やそれを代入した
反復子に対する操作の結果は定義されているでしょうか?
576デフォルトの名無しさん:2008/04/16(水) 20:42:11
ttp://www.asahi-net.or.jp/~yf8k-kbys/newcpp18.html
このサイトを見ながらC++の基礎を勉強しているのですが、このページのデストラクタのサンプルプログラムを
VC++2008EEに打ち込んでも「消滅しました」のメッセージが出ないのですが、
これはVC++側の処理の問題でしょうか?
577デフォルトの名無しさん:2008/04/16(水) 20:44:49
詳しく読んでないからわからんが、派生クラスで基底クラスのデストラクタが呼び出されないとかなら
virtualが抜けてるからとかそんなんじゃね?
578デフォルトの名無しさん:2008/04/16(水) 20:51:17
まだ始めたばかりの初心者です。。
あまりを出さなくてよい、簡単な割り勘のようなのを作っているのですが、
-
#include<stdio.h>

int main(void)
{
int a,b,c;

/*計算の入力 金額*/
printf("金額を入力してください");
scanf("d%",&a);
/*人数*/
printf("人数を入力してください");
scanf("%d",&b);

/*計算と結果の表示*/
c=a/b;
printf("%d/%d=\t%d\n",a,b,c);

return 0;
}
-
これを実行させると、金額を入力してEnterキーを押した時点で変な数字が出てきてしまいます…
なにか足りない気がしますが、何処がおかしいのでしょうか…?
ご教授よろしくお願いします。
579デフォルトの名無しさん:2008/04/16(水) 20:51:27
どのコードを書いて、どういうメッセージは出たのか、
情報が足りなさ過ぎる。
580デフォルトの名無しさん:2008/04/16(水) 20:52:05
>>579>>576
581デフォルトの名無しさん:2008/04/16(水) 20:53:09
>>578
d%
582デフォルトの名無しさん:2008/04/16(水) 20:53:29
scanf("d%",&a);
打ち間違い?
583576:2008/04/16(水) 21:15:39
>>580
スミマセン。。。
//dest_sample.cppのコードをまるっきりそのまま書いて実行したところ、
実行結果例の下2行の「消滅しました」のつく文だけ表示されません。
問題なくコンパイルできますし、上4行の「生成されました」と「呼び出されました」
の付く文は正常に表示されます。
試しに、筆者が書いたものをコピー&ペーストして実行してみましたが、
やはり「消滅しました」のつく、下2行の文が表示されません。
~Nanika(){
cout << "Nanikaのインスタンス" << datum << "が消滅しました。" << endl;
が完全に無視されているような状態です。

宜しくお願いします。
584デフォルトの名無しさん:2008/04/16(水) 21:29:48
コンパイラは何?
585デフォルトの名無しさん:2008/04/16(水) 21:39:59
namespaceにはまっています。
あるソースファイルのnamespaceで囲まれた関数を別のソースファイルでexternしたいのですが、
どうすればいいかわかりません。コンパイルエラーになります。
名前空間名を付けて呼び出してもだめで・・・。
aaa.cpp-----------------------------------
#include <stdio.h>

namespace hoge
{
void Func()
{
printf("HELLO\n");
return 0;
}
}
bbb.cpp------------------------------------

extern void hoge::Func(); ←コンパイルエラー

void main()
{
hoge::Func() ← コンパイルエラー
Func(); ← コンパイルエラー

return;
}
-----------------------------------------
bbb.cppからaaa.cppの名前空間が見えてないっぽいんですがこんな場合どうしたらいいのかわかりません。
ネットでも検索したのですが、複数ファイルに分ける事ができる記述はあっても
やり方が乗ってないので困ってます。どなたかお願いします。
586デフォルトの名無しさん:2008/04/16(水) 21:41:05
namespace hoge{ extereeeen void Func(); }
587デフォルトの名無しさん:2008/04/16(水) 21:41:27
namespace hoge {
 void Func();
}

int main()
{
 hoge::Func();
}
588デフォルトの名無しさん:2008/04/16(水) 21:45:14
ああ、コンパイラはVC++2008EEか。
589デフォルトの名無しさん:2008/04/16(水) 22:00:46
>>586
bbb.cppでexternする場合はコレもnamespaceで囲んであげないといけないと言うことでしょうか!?
やってみたのですがVC++6.0なせいか hogeがシンタックスエラーを起こしてます。
VC++対応していない?明日会社でやってみます。

>>587
586さんと似てるのですが、externしなくてもよいと言うことでしょうか?
これまたVC++6.0ではhogeがシンタックエラーを起こしています。
明日やってみます。
590デフォルトの名無しさん:2008/04/16(水) 22:56:43
VC6 でも問題はないはずなんだが・・・
591デフォルトの名無しさん:2008/04/16(水) 22:57:30
関数プロトタイプはデフォルトで extern ってのは常識だろ?
592デフォルトの名無しさん:2008/04/16(水) 22:59:45
>>583
VC++2008でやってみたけど、ちゃんと表示されたよ。
593デフォルトの名無しさん:2008/04/16(水) 23:09:05
ひょっとしてNanikaのインスタンスを
グローバルで生成したというオチではないだろうなw
594デフォルトの名無しさん:2008/04/16(水) 23:12:02
外部ライブラリのデストラクタの方が後に走るから
グローバル変数にしても cout に問題はないと思う。
というか、グローバルにしても表示された。
595デフォルトの名無しさん:2008/04/17(木) 01:48:09
#include <boost/regex.hpp>

template<typename TChar>
class TCHoge
{
public:
  typedef boost::basic_regex<TChar>  regex_type;
  static int Func(regex_type reg){ return 0; }//ok
  //static int Func(regex_type::flag_type flag){ return 0; }           // NG1
  //static int Func(boost::basic_regex<TChar>::flag_type flag){ return 0; } // NG2
  static int Func2(boost::basic_regex<char>::flag_type flag){ return 0; }   //OK
};

Window2000
Visual C++ 2005 express edition
boost 1.34.1

 NG1 のように記述したいのですが,以下のようなエラーとなってしまいます.

warning C4346: 'boost::basic_regex<charT>::flag_type' : 依存名は型ではありません。
error C2061: 構文エラー : 識別子 'flag_type'

VC6.0 では問題なかったのですが,どのように記述すれば良いでしょうか?
596デフォルトの名無しさん:2008/04/17(木) 02:07:22
×boost::basic_regex<TChar>::flag_type
○typename boost::basic_regex<TChar>::flag_type

だっけ?あまり自信ないや
597595:2008/04/17(木) 03:25:08
>>596 さん,有難う御座います.教えていただいた方法でうまくいきました.

これから typename をつけまくる作業に戻ります…

それでは.
598デフォルトの名無しさん:2008/04/17(木) 03:48:20
>>575
基本的には全部未定義。唯一、デフォルトコンストラクタで初期化したイテレータに、
そうではない値を代入することができる、ってことになるみたい。
24.1p5 の "Iterators can also have singular values ..." あたりにそんなことが
書いてあって、デフォルトコンストラクタで作った Forward iterator は singular value を
持つ(ことがある)とされている。

要するに未初期化のポインタやヌルポインタと同じ扱いってことね。
599デフォルトの名無しさん:2008/04/17(木) 07:27:26
>>597
VC6 だと逆にエラーになるから
もし VC6 でもコンパイルしたいということになりそうなら
後で切り替えられるようにマクロにしといた方がいい。
600デフォルトの名無しさん:2008/04/17(木) 08:28:19
VC6を窓から捨てるのが正解かと
boostでもVC6は切ってるし
601デフォルトの名無しさん:2008/04/17(木) 10:52:55
>>589
プロトタイプ宣言したヘッダファイルを作れ。
つーか、チミのやりかたではnamespaceつくらなくてもアウチなんだけど
602デフォルトの名無しさん:2008/04/17(木) 12:52:38
stlやboostを使っていると、typedefを書く場所に悩みます。
class ClassA { HogePtr pHoge_; };
class ClassB { HogePtr pHoge_; };
この時、typedef boost::shared_ptr<Hoge> HogePtr;はどこに書くのが理にかなっているのでしょうか?
Hoge.h?それともClassA.hとClassB.h?
603デフォルトの名無しさん:2008/04/17(木) 12:56:08
>>602
typedef しないという選択肢は無いのかね?
ほんとに HogePtr に意味があるなら Hoge.h だろうね。
604602:2008/04/17(木) 13:00:36
>>603
すみませんtypedefしない選択肢もありました。
Hoge.hでtypedefするか、typedefしないかの2択ですね。
ありがとうございました。
605デフォルトの名無しさん:2008/04/17(木) 21:40:19
class Hoge {
public:
typedef boost::shared_ptr<Hoge> ptr_t;
};
というのはどうですか?
606デフォルトの名無しさん:2008/04/17(木) 23:27:03
ClassA や ClassB の実装部分を HogePtr の実体から分離するために
typedef 名をつかうってんなら、いっそ
template class <T> class ClassAImpl { typedef boost::shared_ptr<T> Ptr; ... };
で、
typedef ClassAImpl<Hoge> ClassA;
あたりまでやっちゃうのも悪くないと思うよ。
607デフォルトの名無しさん:2008/04/18(金) 01:14:56
inline std::string Reverse( const std::string & src ){
return std::string( src.rbegin( ), std::rend( ) );
}
これくらいシンプルな感じで実装する方法ないですか?
608デフォルトの名無しさん:2008/04/18(金) 01:21:01
ごめん誰か>>607を翻訳して
609デフォルトの名無しさん:2008/04/18(金) 01:29:32
ようするに逆順でイテレーションしたいんだろうさ
610デフォルトの名無しさん:2008/04/18(金) 01:32:28
実装する手間を惜しんでシンプルな設計を考えることは良いことだが、
人に説明する手間を惜しむのは(・A・)イクナイ!!
611デフォルトの名無しさん:2008/04/18(金) 01:40:34
>>608
すいません。>>609ってことです。しかもstd::rend( )って何だよ・・・orz

当然できんだろ、って思ってたらコンパイルエラーになるんすね。
やっぱcopy使うのが一番まともでしょうか?
612602:2008/04/18(金) 01:45:35
>>605
なるほど、それもありましたか。

>>606
ClassAとHogeの分離は考えてなかったです。
考えていたのは、
1、クラステンプレート実体化のコードが長くなるので、stlやboostはtypedefして使うものだと思っていた。
2、shared_ptrを使うという事は、2つ以上のクラス(スコープ)で型を使う事になるので、typedefを1箇所(Hoge.h)にだけ書いて、参照したほうがいいのではないか?
3、しかし、shared_ptrに入れて使うかどうかは、Hoge.hをインクルードして使う側の選択肢であって、使う側の可能性をHoge.hに書いてしまうのはどうか?
といったことで悩んでいました。
613デフォルトの名無しさん:2008/04/18(金) 02:14:07
>>611
よくわからんが std::reverse でも使っとけ
614デフォルトの名無しさん:2008/04/18(金) 02:24:36
世の中にはある程度の割り切りが必要な時だってあるのさ・・・
615デフォルトの名無しさん:2008/04/18(金) 11:03:18
>>611
make_reverse_range(src) // boost::range_ex
src|reversed // pstade::oven

非標準のライブラリ使ってもいいならこんな感じで簡単に書ける

>>612
HogePtrをtemplateにして
template template parameterでboost::shared_ptr等を与える

// hoge.h
struct Hoge { ... };
template< template<typename T> class Pointer >
struct HogePtr {
 typedef Pointer<Hoge> type;
};

// client code
#include "hoge.h"
template< typename T > struct raw_pointer { typedef T *type; };
HogePtr<raw_ptr> raw;

#include <boost/shared_ptr.hpp>
HogePtr<boost::shared_ptr> shared;

これならhoge.hppで#includeしなくてもよくなる筈
616デフォルトの名無しさん:2008/04/18(金) 13:57:34
>>615
×HogePtr<raw_ptr> raw;
○HogePtr<raw_ptr>::type::type raw;
×HogePtr<boost::shared_ptr> shared;
○HogePtr<boost::shared_ptr>::type shared;
ではなくて?

そもそもhoge.hppでshared_ptr.hppの#includeを避けるなら
// client code
Hoge* raw;
boost::shared_ptr<Hoge> shared;
でいいじゃん?
617デフォルトの名無しさん:2008/04/18(金) 22:57:32
>>581
>>582
返信遅くなってしまいました…
そんな単純なミスだったんですね…
ありがとうございました。
618デフォルトの名無しさん:2008/04/19(土) 15:15:17
ベースメンバ初期化で"this"を使用すると警告がでますが、
コンストラクタ内で"this"を使っても警告も何も出ないけど大丈夫なんですか?

警告が出てるのはインスタンスが生成されていることが保証されて無い状態で
そのポインタを読んでいることが原因になっていると考えているのですが、
だとすると、コンストラクタ内で使っても同じことですよね。

警告が出ないのは、そのポインタの先を使用しなければおkって事なんですかね・・。
619デフォルトの名無しさん:2008/04/19(土) 15:20:45
コンストラクタ内ではメンバの実体は既に生成されているから問題ない
どんな値がはいってるかは知らないけどね
620618:2008/04/19(土) 15:58:08
>>619
>>コンストラクタ内ではメンバの実体は既に生成されているから問題ない
なのに
>>どんな値がはいってるかは知らないけどね
とは?

実体は生成されているけど、thisが指しているのはどこか分からないよ
ってことですか?
それとも、実体の中身に何が入っているか分からないよってことですか?
621デフォルトの名無しさん:2008/04/19(土) 16:00:42
ポインタの先を使用しなけりゃ大丈夫。
622618:2008/04/19(土) 16:12:46
>>621
ってことは、コンストラクタでメンバ関数のアドレスを引き渡すのも危ないってことですよね。
623デフォルトの名無しさん:2008/04/19(土) 16:14:00
コンストラクタ内でそのメンバ関数のアドレスを使わなければ大丈夫。
624618:2008/04/19(土) 16:18:31
>>623
なるほど。理解しました。
どうもありがとうございました。
625デフォルトの名無しさん:2008/04/19(土) 16:18:41
実体は生成される途中にある。
だから、this は存在する。
存在するが、その実体は完全に生成されていないので、
その実体を操作しようとすると色々な不具合が生じる。

1. メンバ変数が全て生成されている保証は無い。
  → メンバ変数に触る関数を呼ぶとヤバい。

2. 仮想関数の呼び出しが正常に働かない。
  → class B : public A { B() : c(this) { } void hoge(); C c; };
    とした時、B のコンストラクタ内から仮想関数 hoge を呼ぶと
    どんな状況であろうが B::hoge が呼ばれるが、
    C のコンストラクタ内から渡されたポインタを使って仮想関数 hoge を呼ぼうとすると
    どんな状況であろうが A::hoge が呼ばれる。
    B の基本的な初期化が済んでないので、B::hoge を呼ぶ事は非常に危険ということでそうなるのだが、
    もちろん A::hoge が呼ばれてしまう事も危険っちゃ危険だ。
626618:2008/04/19(土) 16:37:18
ん...また混乱..

>>1. メンバ変数が全て生成されている保証は無い。
>>  → メンバ変数に触る関数を呼ぶとヤバい。
これだと、例えば,
class AAA {
public:
  // 危険?
  AAA(){
    this->value = 5;
  };
 
  // こちらにしなくてはならない?
  AAA():value( 5 ){
  };
 
  void test(){
    cout<<value<<endl;
  };
private:
  int value;
}
ということ?
627デフォルトの名無しさん:2008/04/19(土) 16:55:31
ここで言っているのは、コンストラクタ以外のメンバ関数のことでしょ。
普通、メンバ関数は、コンストラクタによって適切に初期化済みであることを
前提にして書かれているから、
コンストラクタの途中で呼び出すのは、一般的には危険ということ。
628デフォルトの名無しさん:2008/04/19(土) 17:18:51
GCC でやってみたら C::C 内でも B::hoge が呼ばれた。未定義なのかな?
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/6276.txt
629デフォルトの名無しさん:2008/04/19(土) 18:02:59
vptrは初期化リストに先立って初期化されてるはずだから、
実装的には値が不定なだけだと思うけど、
未定義ではあると思うよ。
630デフォルトの名無しさん:2008/04/19(土) 18:04:28
補足。this->nとかの値が不定って意味ね。
631デフォルトの名無しさん:2008/04/19(土) 18:08:30
前に VC6 でやった時は仮想関数テーブルの初期化は最後だったけど、
どっちの仮想関数が呼ばれるかって仕様で決まってんのか?
632デフォルトの名無しさん:2008/04/19(土) 18:15:06
え〜うそ〜!?
基底のコンストラクタから、
派生の仮想関数が呼ばれない、とかの話と勘違いしてない?
633デフォルトの名無しさん:2008/04/19(土) 18:17:17
基底に this は流石に渡さんぜよ。
634デフォルトの名無しさん:2008/04/19(土) 18:32:06
>>631
VC++だと__declspec(novtable)を付けたクラスでは
vtblの初期化が行われないなんて独自拡張がある。
(最派生クラスだけnovtable無しにして使う)

これ使っていないか?
635デフォルトの名無しさん:2008/04/19(土) 19:41:56
novtableいいよねー
コード縮むし
636デフォルトの名無しさん:2008/04/19(土) 20:55:37
    |┃三             
    |┃              
    |┃ ≡    _、_   
____.|ミ\___( <_,` )  
    |┃=___     \   
    |┃ ≡   )ATL 人 \ ガラッ
637デフォルトの名無しさん:2008/04/19(土) 21:20:55
class Derived : Base {...}

void f(){
  Derived v;
}

this->vptr = &Base::vtbl → Base::メンバ初期化 → Base::ctor
→ this->vptr = &Derived::vtbl → Derived::メンバ初期化(定義順にctor) → Derived::ctor

Derived::dtor → Derived::メンバ破棄(定義逆順にdtor) → this->vptr = &Base::vtbl
→ Base::dtor → Base::メンバ破棄(定義逆順にdtor) → this->vptr = 不定値

こういう流れになるはず。VC6も。
638637:2008/04/19(土) 21:28:41
表現がおかしかったので訂正。

× Base::メンバ初期化
○ Base::定義順にメンバ初期化
× Derived::メンバ初期化(定義順にctor)
○ Derived::定義順にメンバ初期化

ctorは「メンバの暗黙の初期化・初期化リストによる初期化」を含まないコンストラクタの中身。
dtorは「メンバのデストラクタ呼び出し」を含まないデストラクタの中身。
639デフォルトの名無しさん:2008/04/19(土) 23:10:47
VCの実装を見る限りcinやcoutはextern修飾されてるみたいですが、
宣言のみの必要な定義のいらないこれらの様なものを自分でも書くとき、
一般的にどのコンパイラでも単にexternを付けておけば良いんでしょうか?
640デフォルトの名無しさん:2008/04/19(土) 23:21:00
externが、必要がでるまでどこかで定義された実体を探す事がないという保証があるかどうか?
641デフォルトの名無しさん:2008/04/19(土) 23:25:46
日h(ry
642デフォルトの名無しさん:2008/04/22(火) 15:26:08
template<class T> struct A { struct B {}; };
template<class T> void f( typename A<T>::B ) {}
と定義して
f( A<int>::B() );
とすると

'void f(A<T>::B)' : テンプレート 引数を 'T' に対して減少できませんでした

というエラーが出るのですが、入れ子クラスではテンプレートの引数を推測でき
ないのでしょうか?
643デフォルトの名無しさん:2008/04/22(火) 15:49:31
f( A<int>::B() );

f<int>( A<int>::B() );
と推測できないかってこと?

それは無理がありすぎるな。
644デフォルトの名無しさん:2008/04/22(火) 17:09:44
逆にboost::implicit_castがこれを使っていて、
推論を抑えるため、引数の型をtypename mpl::identity<T>::typeにしている。
645デフォルトの名無しさん:2008/04/22(火) 19:09:03
BがAのテンプレートパラメータTの値をtypedefの形で保持してそれをf側で参照するようにしてやれば可能になりそうだけど
そうするとfを関数オブジェクトにしないといけなくなってC++の暗黒面に突入する…と
本当にunk言語だな
646デフォルトの名無しさん:2008/04/23(水) 17:10:39
何で
std::auto_ptr<char> x( new int );
はコンパイルエラーにならないんですか?
647デフォルトの名無しさん:2008/04/23(水) 17:19:09
おまえがどんなコンパイラと、どんなSTLの実装使っているのか非常に気になる。
648デフォルトの名無しさん:2008/04/23(水) 17:23:34
コンパイラは VC8 SP1 で STL はコンパイラ付属です。
649デフォルトの名無しさん:2008/04/23(水) 22:11:04
VC8って2005だっけ?
2008ではエラーになったぞ。
650デフォルトの名無しさん:2008/04/24(木) 00:38:29
8は2005
651デフォルトの名無しさん:2008/04/24(木) 09:47:20
VC++2005Expressではエラーになった
652デフォルトの名無しさん:2008/04/24(木) 12:12:58
VC7.1 だとエラーになりました。

Microsoft Visual Studio 2005
Version 8.0.50727.762 (SP.050727-7600)
だとなぜかエラーになりません。

もしかして C++ コンパイラはエラーを出す義務はないのかな?
653デフォルトの名無しさん:2008/04/24(木) 13:26:29
多分それはない。
コンパイラのバグか、誰かがヘッダ書き換えちゃったとか。
654デフォルトの名無しさん:2008/04/24(木) 15:07:19
デバッガで追いかけたら new int が一旦 std::auto_ptr_ref<char> に
変換されてから std::auto_ptr<char> に変換されていました。
std::auto_ptr_ref<T> は void* 型でポインタを記憶しているので
int 型は消えていました。
memory ヘッダーを確かめると確かにエラーが出ないはずです。
この動作は std::auto_ptr の仕様でしょうか?
655デフォルトの名無しさん:2008/04/24(木) 15:34:39
656デフォルトの名無しさん:2008/04/24(木) 15:45:29
いまだに信じられんな。もうすでにVC8なんて使っていないんだが、
それほど悪いコンパイラとSTLじゃなかったはずだが。

とりあえず>>654の話から想像すると、
rvalueとlvalueの境を越えるための、あまり汎用的に使い道のない、
汚いトリックを使ってauto_ptrを実装しているが(オーバーロードとtemplate argument deductionのわずかな違いを利用するやつ)
普通に使う際にも、そのトリックが働いてしまうって事かな。
STLの実装の問題っぽいかなぁ。
ふつうauto_ptr_refのメンバをvoid *にしなければならない理由はないよな。
657デフォルトの名無しさん:2008/04/24(木) 15:48:53
>>655
あ、>>656に加えて、auto_ptr_refのコンストラクタがexplicitじゃないのか。
だめじゃん、P.J. Plaugerさん。
658デフォルトの名無しさん:2008/04/24(木) 19:51:53
失礼
リソースの 切り離し / 復元 を実行するメソッドの命名に困っているのですが
この意味に近くて使いやすい単語のペアはありませんかね?
機能的に必ず対になるものです。

候補としては
[Detach / Restore] Detach の対義語は Attach だしな
[Detach / Attach] Attach は「復元」では無い気がする
[Destruction / Resotre] Destが長い
[Destroy / Restore] Destory は Create のペアとして使ってきたので控えたい
ですが、どうも腑に落ちません。
659デフォルトの名無しさん:2008/04/24(木) 19:58:10
日本語の「切り離し」と「復元」はそもそも対義語じゃないよね・・・
切り離しとその反対なら、Detach / Attach だろうし、
復元とその反対なら、Save / Restore だろう。

Destruction なんて破壊しちゃうわけでさ、英語以前に日本語の
「切り離し」「復元」ってのがそもそも違うんじゃないか?
660658:2008/04/24(木) 20:08:51
>> 659
> 英語以前に日本語の「切り離し」「復元」ってのがそもそも違うんじゃないか?
うーむ・・仰るとおりですね

切り離しを実行すると 消失 という状態になる処理だったので
それを元に戻す意味で 復元 と考えていたのですが
もう少し考え直してみます。 ありがとうございました
661デフォルトの名無しさん:2008/04/24(木) 20:12:44
漏れはホンちゃんの処理の準備のためのナニにはPrepareXXXを結構使うな。
オフスクリーンビットマップやら何やらの準備とか。
662デフォルトの名無しさん:2008/04/24(木) 21:22:36
release / acquire
663デフォルトの名無しさん:2008/04/24(木) 22:20:14
>>660
Disconnect / ReConnect とか、Detach / ReAttach とかは?
664658:2008/04/24(木) 22:43:04
>>661
Prepare
今回は使いそうに無いけど、ひとつ賢くなりました

>>662
そういえば DirectInput に Acquire / UnAcquire (だったかな)ってのがありますね
これ良いかも

>>663
Disconnect / ReConnect
接続とはちょっと違うんですわ

ありがとうございました
スマートに命名出来るように、もうすこし設計から見直すことにします
665デフォルトの名無しさん:2008/04/24(木) 22:50:04
template <template<class> class T>
このようなテンプレートテンプレートパラメータが
なぜこんな書き方ができるのか今一理解できません。
誰か上手いこと説明してください
666デフォルトの名無しさん:2008/04/24(木) 22:59:29
なぜ出来るのかって、そりゃ出来るように言語仕様を改定して
コンパイラが対応したからだろ・・・
667デフォルトの名無しさん:2008/04/24(木) 23:34:09
class X を渡せる奴は
template <class X> と書くんだから
template <class A> class T を渡せる奴は
template <template <class A> class T> と書けるようにするのが自然だろう。
むしろ他にどんな書き方があるのかと問いたい。
668デフォルトの名無しさん:2008/04/24(木) 23:54:08
>>667
あぁ納得。
<template <class A>

最初の例だとAの部分が無かったので混乱してました
669デフォルトの名無しさん:2008/04/25(金) 20:13:29
std::exception のメソッドの例外指定はいつの間にかなくなってしまったんですか?
ttp://msdn2.microsoft.com/ja-jp/library/c4ts6d5a(VS.80).aspx
を見るのすべてのメソッドに例外指定がないんですけど。
今まで std::exception が例外を投げないことを前提にプログラムを作ってきたんですが。
670デフォルトの名無しさん:2008/04/26(土) 01:47:18
現行規格でも次期規格の最新のドラフトでも throw() ついてるから。
671デフォルトの名無しさん:2008/04/26(土) 02:01:34
だから聞いてるんじゃね
672デフォルトの名無しさん:2008/04/26(土) 10:46:10
throw() は例外を投げない事を保証するが、
unexpected() が呼ばれて落ちる事もあるので
「throw() がついてないからどんな例外が呼ばれるか分からないから
 落ちる可能性があるかもしれないのか不安だよ!」
ってのは意外とナンセンスな悩み。
673デフォルトの名無しさん:2008/04/26(土) 11:32:34
>>672
ナンセンスな私的だな。例外安全性について勉強し直せば。
674デフォルトの名無しさん:2008/04/26(土) 11:35:43
例外指定にない例外を投げたらunexpected()呼ばれるんじゃなかったっけ

つまり例外指定はあんま意味ナス
675デフォルトの名無しさん:2008/04/26(土) 11:40:29
throw()は意味あるよ。関数の実装者がユーザに対して例外を投げない事を保証するものだから。
ユーザはthrow()を見て、例外不送出であることを期待してコードを書く事ができる。

unexpected()が呼ばれる事で、その関数の例外指定に問題があるか、実装に問題がある事をユーザ/実装者が知る事ができる。
676デフォルトの名無しさん:2008/04/26(土) 11:58:31
VCは例外指定無視する(そして"実装されてないお"と警告をだす)のでVC付属のライブラリからも外しちゃったんじゃない?
677デフォルトの名無しさん:2008/04/26(土) 12:02:46
throwをつけると、おき得る例外を特定できるから、それを期待してプログラムを書ける。
なのにそれ以外の例外が投げられるという例外中の例外がunexpectedなのだな。例外にも階層があるんだね。
678デフォルトの名無しさん:2008/04/26(土) 12:16:40
>>676
空のthrow()だけ対応していなかったっけ?
679デフォルトの名無しさん:2008/04/26(土) 12:31:32
>>678
なんかそんな気もする
帰ったら確認してみるよ
680デフォルトの名無しさん:2008/04/26(土) 12:38:39
>>678
そだよ。
書いても警告が出るだけだから。
681676, 679:2008/04/26(土) 20:00:39
vc9で確認してみた

Debugビルドだと、throw()指定がついた関数内に直接throw文を書くとコンパイル時に警告C4297が出る。
実行時はthrow()指定無視

Releaseビルドだと、throw()指定がついた関数内に直接throw文を書くとコンパイル時に警告C4297が出る。
実行時はthrow文のところでterminateによりabort

のようだ
682デフォルトの名無しさん:2008/04/26(土) 20:22:06
VC9は何かバグバグだな
早くSP1出して欲しい
でも年末とか言ってたような希ガス・・・・orz
683デフォルトの名無しさん:2008/04/26(土) 21:26:34
>>669
例外指定があろうとなかろうと、
投げてくる(こない)例外の種類は、規格通りだから安心して使っていいよ。
684デフォルトの名無しさん:2008/04/26(土) 22:13:35
void f( T a ) {}

f の呼び出しで a を生成するときに起きる例外は f の中で発生する
例外ですか,それとも外で発生する例外ですか?
685デフォルトの名無しさん:2008/04/26(土) 22:16:42
686なにがだ:2008/04/26(土) 22:30:18
>>684
f()に入れる前に出ちゃってるんだから大丈夫。
687デフォルトの名無しさん:2008/04/26(土) 22:31:58
もう、出しちゃったの?
688デフォルトの名無しさん:2008/04/27(日) 17:46:33
Winsock2.0で非同期通信について教えてくれ

connectメソッド使ってサーバに接続要求して
サーバ側でACCEPTメッセージちゃんと受け取って
接続できてるのに戻り値が0にならないのは何で?
689デフォルトの名無しさん:2008/04/27(日) 17:58:54
とりあえずWSAGetLastErrorでエラー内容調べてみたら?
690デフォルトの名無しさん:2008/04/27(日) 18:06:54
>>689
やってんだけどわかんないんだ

非同期通信の場合WSAEWOULDBLOCKが返されるのは正常
という記事は見つけたんだけど、鯖立ててない状態で接続しても
WSAEWOULDBLOCKしか返らないからエラー処理出来なくて困ったちゃん
691デフォルトの名無しさん:2008/04/27(日) 18:16:49
http://msdn2.microsoft.com/en-us/library/ms887913.aspx
>With a nonblocking socket, the connection attempt cannot be completed immediately.
>In this case, this function will return SOCKET_ERROR and WSAGetLastError will
>return WSAEWOULDBLOCK.
692デフォルトの名無しさん:2008/04/27(日) 20:46:47
C++のnamespaceとオブジェクトに関連した質問させて下さい。

namespace Aにあるクラスまたは構造体のオブジェクトを、
namespace Bのクラスに引数として渡したいのですが、どのように
記述すればいいのでしょう?出来ればnamespace AとBは別々に、
それがダメならnamespace Aの中にBがいるように出来ればと
思っています。

C++を触りはじめたばかりでわかっていないことが多いのですが、
よろしくお願いします。
693デフォルトの名無しさん:2008/04/27(日) 21:26:36
namespace AのclassXなら「A::X」
694デフォルトの名無しさん:2008/04/28(月) 15:26:11
std::vector::size_type 型のオブジェクトは std::size_t 型の
オブジェクトに変換できるでしょうか?
695デフォルトの名無しさん:2008/04/28(月) 16:28:10
>>694
符号なし整数で、difference_typeの全ての非負数を表す事ができる。
としか書かれてないから、実装依存じゃないかな。
696デフォルトの名無しさん:2008/04/28(月) 16:38:32
教えてください。
Visual Studio 2005をつかっています。
クラスのコンストラクタ内で動的に2次元配列を生成し、
ファイルから値を入力したいのですが、
デバッグ(ローカル,this,vec_x内)で確認すると、2次元配列にはなっているのですが、
行数、列数で共に1となってしまっています。
int **vec_x;
int **vec_y;
と宣言し、コンストラクタ内で、
vec_x = new int * [ size_y ];
vec_y = new int * [ size_y ];
for(i = 0; i<size_y; i++){
vec_x[i] = new int[size_x];
vec_y[i] = new int[size_x];
}
size_y,size_xは初回のnewの次点ですでに、
300,200となっていることは確認済みです。
697デフォルトの名無しさん:2008/04/28(月) 16:43:38
>>696
何を根拠に行数、列数が1と判断したのか詳しく。
つーか、vector<vector< int> >使ったら?
698デフォルトの名無しさん:2008/04/28(月) 16:48:51
>>696
デバッガでは配列の要素数は型情報として存在しない限り
表示されないというか new [hoge] で取ったサイズは表示されないというか、
要するにただのポインタなので要素は1つしか表示されないというか、
まぁそんな感じ。
699696:2008/04/28(月) 16:51:46
>>697
デバッグで、ローカル変数タブからです。
this以下、vec_x(int **)を見ると、
(int *)に対応するところが1段しかありませんでした。
さらに、その下(?)の階層にも要素はひとつしかありませんでした。
>>698
その要素に値を入力したとき、
うまく領域が確保できていればどう表示されるんでしょうか。
700デフォルトの名無しさん:2008/04/28(月) 16:59:05
>>699
詳細は>698の通り。そのデバッガは(newで確保した)可変長配列に対応していないのだろう。
確保できていたかどうかを知る手段はない。
確保に失敗したかどうかは例外が送出されるので受け取ればいい。
つーか、>697の最終行。
701696:2008/04/28(月) 17:13:14
むしろ、その後の値の入力に問題があるのかもしれません。
ifstream ifs("FILE_NAME");
ifs >> size_x >> size_y;

for( i = 0;i<size_y;i++){
 for( j = 0;j < size_x; j++){
  ifs >> vec_x[i][j] >> vec_y[i][j];
 }
}
としています。
入力ファイルの中身は、
整数(半角スペース)整数
整数(半角スペース)整数
...
となっており、最初にsize_x,size_yを入力しています。
size_x,size_y,vec_x[0][0]は正しく入力されたのですが、
vex_y[0][0]には正しい値は入っていません。
その後のvex_x,vec_yの各要素の値に関しても同様に正しい値は入力されませんでした。

>>697
STLはややこしくて全く手をつけていません。
お恥ずかしい限りですが…。
702デフォルトの名無しさん:2008/04/28(月) 17:30:54
>>701
g++ で一応試したけど、配列は >>696 で問題無いよ。
俺も STL 使った方がいろいろと簡単だとは思うけど。
703デフォルトの名無しさん:2008/04/28(月) 17:40:17
STLに限らず、まとまった規模の情報は何でもそうだけど、遠目に見ているうちは
頻繁に使うものと滅多に使わないものが「同じ大きさ」に見えるんで、
無駄に全容を眺めてしまって、「難しそうだなぁ」という気持ちばかり膨らんでいく。

実際には「STLを使う」ってのは、その殆どがつまり「コンテナを使う」ってことで、
これ自体はめちゃくちゃ簡単な話だよ。
704696:2008/04/28(月) 18:00:02
ありがとうございます。
STLを勉強してみたいと思います。
今回は(x,y)のようなベクトルによって構成された、
2次元配列を二つ作ることを考えています。
vector<vector< int> > vect1(size_y,vector<int>(size_x));
として、vect1[y][x]として要素にアクセスすればいいのでしょうか。
ttp://gimite.net/bcbqtree/qtreemain.cgi?mode=thread&thread=162

この場合のコンストラクタの動作が理解できません。
第二引数のvector<int>(size_x)でvect1を初期化するのでしょうか。
705デフォルトの名無しさん:2008/04/28(月) 18:57:24
>>704
それで使い方はいいよ。

違うよ。2個目の引数は vect1 の各要素を初期化というか instantiate してる。
constructor は 2 つ引数あるときは個数と各要素。
706デフォルトの名無しさん:2008/04/29(火) 21:50:55
>>705
下の文に引用が無いから
> それで使い方はいいよ。
> 違うよ。
が繋がった感じで、なんかワロタ
707デフォルトの名無しさん:2008/05/01(木) 13:42:23
クラスAからpublic派生したクラスBで、クラスA分のメンバ関数をprivateにしたいんですが
Virtual付いてると宣言だけじゃ駄目なんでしょうか?
環境はBCB5+XPです

class a {
public:
void Test1() {};
virtual void Test2() {};
};
class b : public a {
private:
void Test1(); //OK
virtual void Test2(); //リンカエラーが出る
};
708デフォルトの名無しさん:2008/05/01(木) 13:56:01
virtualは関数の実体を定義しないとエラーになるよ。
709デフォルトの名無しさん:2008/05/01(木) 13:58:16
それが許されたとして、aの中でよんでいるTest2はどうなるのか興味浦々
710デフォルトの名無しさん:2008/05/01(木) 14:13:48
う〜んそうだったんだ。
a.Test2()で実体があるから、問題ないんじゃないかと思ってたけど
違うのか。
すごく勉強になったよ。ありがとう〜
711デフォルトの名無しさん:2008/05/01(木) 15:04:23
class b : public a {
private:
using a::Test1;
using a::Test2;
};

やりたいのはこういうことか?
712デフォルトの名無しさん:2008/05/01(木) 17:43:05
>>711
この書き方は知らなかった。
usingについて調べてみます。
713デフォルトの名無しさん:2008/05/04(日) 23:24:42
じぇねれーてぃぶこーどって本
買ったけどC++のソース部分読めない
たじゅけて
714デフォルトの名無しさん:2008/05/05(月) 00:30:03
出版社に送って新しいのと取り替えてもらえ
715デフォルトの名無しさん:2008/05/05(月) 00:47:17
無限ループになる悪寒
716デフォルトの名無しさん:2008/05/05(月) 07:55:38
>>714
当社では、「落丁・乱丁」の場合のみお取替えをさせていただいております。

大変申し訳ありませんが、「ソースコードが理解できない」お客様につきましては、
対応いたしかねますので、ご了承いただけますよう重ねてお願いいたします。
717デフォルトの名無しさん:2008/05/05(月) 13:45:51
>>713
何がそんなに難しいの? template とかの勉強が必要なのかな?
718デフォルトの名無しさん:2008/05/06(火) 00:30:53
じぇねれーてぃぶこーどなんて本あったっけ?
719デフォルトの名無しさん:2008/05/06(火) 00:38:16
日本語ではなかった気がする
720デフォルトの名無しさん:2008/05/06(火) 10:14:01
721デフォルトの名無しさん:2008/05/06(火) 11:32:55
hoge
722デフォルトの名無しさん:2008/05/06(火) 11:39:15
int main ()
{
static int i (0);
struct Local
{
static void increment ()
{
++ i;
}
};
Local::increment ();
}
関数内のクラスのstaticメンバ関数(Local::increment)から
関数内の変数(i)を触れるのは規格に合ってる?
g++.real (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
では触れるのだけど.
723デフォルトの名無しさん:2008/05/06(火) 14:12:30
スタティックなメンバ関数からスタティックなメンバ変数が見えるのはいいんでないかい?
別に矛盾はないと思うし。
スタティックなメンバ変数ってのは、スコープ限定のグローバル変数みたいなもんだしね。
724デフォルトの名無しさん:2008/05/06(火) 15:28:06
>>723
そういう事なんだろうね。俺も >>722 さんの code 見てちょっと
えっ?て思ったけど、気分悪いがはっきりと間違っているとも言えない。
実際 compile してみると走るし(g++ 4.1.1)。どちらの static でも
外せば compile しない。
725722:2008/05/06(火) 15:42:33
>>723,724
規格に合っているみたい.

9.8.1に
722ほぼそのまんまの例が載ってました.
726デフォルトの名無しさん:2008/05/06(火) 23:05:22
int* array[10];
ってnewでやる場合どう書けばいいですか?
727デフォルトの名無しさん:2008/05/06(火) 23:07:39
array[0] = new int[931];
728デフォルトの名無しさん:2008/05/06(火) 23:26:29
>>726
もっと分かるように質問しろお( ^ω^)
729デフォルトの名無しさん:2008/05/06(火) 23:31:01
int** array = new int*[10];でしょjk
730デフォルトの名無しさん:2008/05/06(火) 23:32:22
C++のソースコードをアセンブラのコードに変換する方法があるって聞いたんですが
どうやればいいか教えてください
コンパイラはVCです
731デフォルトの名無しさん:2008/05/06(火) 23:34:11
コンパイラオプションで「アセンブリコードを出力する」に設定する
732デフォルトの名無しさん:2008/05/06(火) 23:36:49
730です
ありがとうございます
733デフォルトの名無しさん:2008/05/07(水) 00:02:34
void F( vecotr<int> &vec )
{
struct T
{
void operator()( int i ){ printf( "%d\n", i ); }
};

for_each( vec.begin(), vec.end(), T() );
}

こういう奴で、struct TをFのスコープ外にすると通るんだけど、
スコープ内だと通らない。
なんで?

なんで?って考えちゃダメ?
734デフォルトの名無しさん:2008/05/07(水) 00:04:20
>>733
関数ないクラス、構造体はtemplateクラスやtemplate関数にtemplate引数として渡せないと仕様で決まっている。
735デフォルトの名無しさん:2008/05/07(水) 00:05:23
誤字修正
x 関数ないクラス
o C++仕様もまともに知らない奴は死ね
736デフォルトの名無しさん:2008/05/07(水) 00:07:32
x 関数ない
o 関数内

こういうことだろ
737デフォルトの名無しさん:2008/05/07(水) 00:18:35
x こういうことだろ
o べ、別にあんたの為に修正してやってるんじゃないんだからねっ!
738デフォルトの名無しさん:2008/05/07(水) 00:35:33
>733
C++STDの14.3.1.2で不可になってますな。
コンパイル時に特定する必要があるので、外部リンケージの無い要素を指定できないんですな。
そういう意味で文字列リテラルも不可。
#文字列リテラルを実引数にできると色々と面白いんだけど、しようがないか……
739デフォルトの名無しさん:2008/05/07(水) 00:49:27
外部リンケージ?
740デフォルトの名無しさん:2008/05/07(水) 18:10:55
ケータイ小説・千の風になっての評価

評価者:ミカ  評価:★★★★★
ミカと同じ名前で同じ歳の子がこんなひどい人生を送るなんて!!
信じられない!!
一晩中泣きました!!

評価者:サナエ 評価:★★★★☆
これがあたしたちのリアル。

評価者:ち†ょ⊃ 評価:★★★★★
寝ゐ前|ニ言売ゐ女台め†ニяа止маω†ょ<τ
冫欠σ日シ立L≠†ょカヽ〃яа学木交|ニ彳テL≠маU†ニ

741デフォルトの名無しさん:2008/05/07(水) 19:53:49
ちなつ
寝る前に読み始めたら止まんなくて
次の日泣きながら学校に行きました

同じ文字を複数の文字にあてたり、いきなりローマ字とか出てくるとワケワカメになるね。
742デフォルトの名無しさん:2008/05/07(水) 20:39:31
ドストエフスキー小説・罪と罰の評価

評価者:ラスコーリニコフ  評価:★★★★★
僕と同じ名前で同じ歳の人がこんなひどい人生を送るなんて!!
信じられない!!
一晩中泣きました!!

評価者:ドストエフスキー 評価:★★★★☆
これがあたしたちのリアル。

評価者:ポルフィーリィ 評価:★★★★★
予審前に読み始めたら止まんなくて
次の日泣きながら仕事に行きました
743デフォルトの名無しさん:2008/05/08(木) 00:57:43
おい
自演してる奴がいるぞ
しかも評価は控えめw
744デフォルトの名無しさん:2008/05/09(金) 16:17:28
1         2           3           4

.     __                       __             _ 
    ,i,_,i_        ,-,_         ,-i,_,l 、      :.. :. ≡=-i'__l, 
    |  `i         /'-' `i         //l   l       iコ==ラ`'i ti 
    | lヽi li,   →  | lヽl li   →   l i,,l   l |   →     ./  /l/
    | l-'l |,l       | | // l        `"|iコ=''         /  /
.    'Fヲ|,H      E三l_l_A         | .i .|         /  / 
    ,i_| .| |                   | || |         i' /l .l,
     -'‐'                      | || |_       l l .ヽ,ヽ, 
                          ‐' ' `‐'       -'-'  -'-' 
    脱ぐ       たたむ      プログラムを     src と dest を
                         つくる      まちがえる。
745デフォルトの名無しさん:2008/05/09(金) 19:02:05
>>742
>評価者:ポルフィーリィ 評価:★★★★★
>予審前に読み始めたら止まんなくて
>次の日泣きながら仕事に行きました

あんたが言うせりふやない。
746デフォルトの名無しさん:2008/05/09(金) 19:23:43
>>744
ワロタ
747デフォルトの名無しさん:2008/05/10(土) 15:18:13
重複しない複数の座標値、x,y,zという3つのキーを用いて、
そのキー(座標)の要素に値を代入、変更する処理を行おうと思っています。

現在、

class XYZ
{
 int x;
 int y;
 int z;
 int value;
};

としてXYZの配列を計算したい領域分だけ確保しているのですが
任意のx,y,zで値の変更があった場合,そのキーの要素を検索して参照、代入する方法として
何かよい方法はありませんでしょうか?
よろしくお願いいたします。
748デフォルトの名無しさん:2008/05/10(土) 15:20:47
管理が冗長すぎるだろ
749デフォルトの名無しさん:2008/05/10(土) 15:30:18
std::map<int, std::map<int, std::map<int, int> > > m;
m[x][y][z] = value;
750デフォルトの名無しさん:2008/05/10(土) 15:45:35
m[x][y][z]って・・・
751デフォルトの名無しさん:2008/05/10(土) 15:56:35
志村XYZのDVDって出てたっけ?
752デフォルトの名無しさん:2008/05/10(土) 17:33:03
>>747
言いたいことがよくわからない。
キーが与えられたら要素を返す method と代入する method (というか
メンバ関数)を作るってことじゃないの?変更がどうあるのかもよくわからん。
753デフォルトの名無しさん:2008/05/10(土) 17:47:52
XYZにoperator< を定義してsetに突っ込む
754デフォルトの名無しさん:2008/05/10(土) 17:52:37
>>747
3次元座標値ってどんな領域なのよ?

まず問題の概要を説明しやがれ
このスカポンタン
755デフォルトの名無しさん:2008/05/10(土) 17:55:46
>>754
そこは重要じゃないだろ
756デフォルトの名無しさん:2008/05/10(土) 18:01:09
これでいいだろ
#include<map>
class XYZ {
int x, y, z;
public:
XYZ(int x, int y, int z) : x(x), y(y), z(z) {}
bool operator<(const XYZ& rhs) const {
return x < rhs.x || (x == rhs.x && (y < rhs.y || (y == rhs.y && z < rhs.z)));
}
};
int main()
{
std::map<XYZ,int> m;
m[XYZ(0,1,2)] = 100;
}
757デフォルトの名無しさん:2008/05/11(日) 05:35:20
#include <new>
としているコードを見かけますが、
わざわざ<new>をインクルードするのなぜなのでしょうか?
インクルードしなくてもnewは普通に使えますよね?
758デフォルトの名無しさん:2008/05/11(日) 11:02:53
いらないと思うんだった、コメントアウトして再コンパイルしてみればいいんじゃね?

単に習慣でインクルードしてるだけかもしれないし。
759デフォルトの名無しさん:2008/05/11(日) 11:14:42
placement new, std::nothrow, std::bad_alloc を利用する際にインクルードするヘッダファイルであって、
普通の new を使うためにインクルードするヘッダファイルではない。
760デフォルトの名無しさん:2008/05/11(日) 11:23:57
>>757
precement newやnew演算子のオーバーロードをするときに使う。
761デフォルトの名無しさん:2008/05/11(日) 11:28:16
オーバーロードする際に必要だっけ?
762デフォルトの名無しさん:2008/05/11(日) 11:28:52
そんな事はない
763デフォルトの名無しさん:2008/05/11(日) 11:29:54
だよねー
764デフォルトの名無しさん:2008/05/11(日) 12:34:18
かわいい女の子が寝る前に
1分間枕元に立ってくれるための
おまじないだと、先輩から聞いたことがる。
765デフォルトの名無しさん:2008/05/11(日) 15:51:39
映画版呪怨ですね。わかります。
766デフォルトの名無しさん:2008/05/12(月) 00:39:48
struct xstring_traits{
   bool is_w() const {...}
   ...
};
struct vstring_ref { // デフォルトコピーコンストラクタ使用
   const xstring_traits* tr_;
   const char* begin_;
   const char* end_;

   const wchar_t* wbegin(){return tr_->is_w() ? reinterpret_cast<const wchar_t*>(begin_) : NULL;}
   ...
};
struct vstring_buffer {
   const xstring_traits* tr_;
   char* begin_;
   char* end_;
   ...
};
struct vstring {...}; // コピーでメモリ再確保
767766:2008/05/12(月) 00:40:35
(続き)

やっぱ引数がconst std::stringだと
std::string以外から受け取る場合のコストが気持ち悪いし、
const char* でことあるごとにstrlenとかするのも無駄だし、
WindowsだとTCHARとかの場合もあるけど、
WinAPIに関係無い部分にまで<tchar.h>入れるの嫌だし。

で、ただでさえ多い文字列クラスをさらに増やすのかと
葛藤しつつも自作文字列クラスを・・・。

皆はやっぱり普通にstd::string?
Windowsの場合は、
typedef std::basic_string<TCHAR>する人もいるよね。
768766:2008/05/12(月) 00:41:33
×引数がconst std::string
○引数がconst std::string&
769デフォルトの名無しさん:2008/05/12(月) 00:55:18
俺は、普段はconst std::string&で済ます。
std::basic_string<TCHAR>のtypedefもWindowsプログラムならよく使う。
767も言うコストが気になるならRangeを引数に取るテンプレートにする。
770デフォルトの名無しさん:2008/05/12(月) 01:29:45
スレチだけど俺は TCHAR でちゃんと動くコード(mbcsをちゃんと処理するコード)を
書く気はさらさらないので、欺瞞的なTCHARの使用はなるべく避けてWCHARにしてる。
771デフォルトの名無しさん:2008/05/12(月) 01:44:18
俺も全部 TCHAR で書いてるけど、string::find とか平気で使ってるわ。
mbcs じゃほとんど動かんコードになってる。
772デフォルトの名無しさん:2008/05/12(月) 07:10:43
>>767
文字数が必要ならこうする手も。

void hoge(const char* str, size_t len) { }
inline void hoge(const std::string& str) { hoge(str.c_str(), str.length()); }
773デフォルトの名無しさん:2008/05/13(火) 13:28:40
なんで、private継承、protected継承すると、アップキャストができなくなるのだ?
774デフォルトの名無しさん:2008/05/13(火) 13:44:30
外からprivateなメンバにアクセスできないのと同じ
外からprivateな基本クラスにはアクセスできない
775デフォルトの名無しさん:2008/05/13(火) 13:48:23
>>773 外からできなくなるだけで、中からならアップキャストできるよ。
776デフォルトの名無しさん:2008/05/13(火) 17:32:36
private継承するboost::operatorsがなんで動作するのかも良くわかんないな。
777デフォルトの名無しさん:2008/05/13(火) 17:41:24
分かんない事ばかりなのに使わなければならないC++って、怖くね?
778デフォルトの名無しさん:2008/05/13(火) 17:47:31
>>776
friend関数はクラスのメンバではないから・・・かな?

class A {
private:
  friend void foo() { ... } // メンバのように見えるけど実はグローバル関数なのでアクセス制御は効かない
};
int main() {
  foo();
}
779デフォルトの名無しさん:2008/05/13(火) 17:48:13
C++以外の言語も使いますが分からないことだらけです。
780デフォルトの名無しさん:2008/05/13(火) 19:36:07
何が分からないか判っていれば解ったも同然だ
781デフォルトの名無しさん:2008/05/13(火) 19:54:24
friend関数、VC2005からtemplate<class T>を頭につけないと
コンパイルが通らなくなったんですね。C++0xはまだなのに
こういう仕様変更はひそかにやってるんですか?

それとも、もともと規格書にはこう決められていてやっと
Vc++2005で対応できた、ということですか?
782デフォルトの名無しさん:2008/05/13(火) 20:31:33
>>777
わかんない部分は無理して使う必要はないし。
でも、わかった後それを使うと今までだらだら長く書いていたコードがすっかりコンパクトにまとまってショックを受けることが多々ある。
783デフォルトの名無しさん:2008/05/13(火) 20:43:20
>>781
それは後者

でも前者みたいなひそかな変更もVC++はよくやる。
いや、きちんと文書化されているけどね。
例えばtype traits支援とかC99の%a書式とか。
784デフォルトの名無しさん:2008/05/15(木) 12:41:47
もう C++ なんて好きでもないし使いもしない理由。
ttp://www.hyuki.com/yukiwiki/wiki.cgi?WhyINoLongerLikeOrUseCPlusPlus

悔しいけど納得した。
785デフォルトの名無しさん:2008/05/15(木) 13:24:39
確かにめんどくさいし手間が掛かる…
786デフォルトの名無しさん:2008/05/15(木) 14:04:26
C++ Programming Languageを端から端まで二度読める知能があれば右辺値参照ごときにどうして瞼が落ちるのか。
787デフォルトの名無しさん:2008/05/15(木) 14:14:04
落ち着かない仕様
時間の掛かる修正
度重なる保守
788デフォルトの名無しさん:2008/05/15(木) 14:15:27
C++は仕事に向かない言語とういのには同意だな
789デフォルトの名無しさん:2008/05/15(木) 14:30:05
C++ Programming Languageを二度読むのに必要なのは知能ではなくて忍耐力だからな
790デフォルトの名無しさん:2008/05/15(木) 14:57:10
性能に取り憑かれているのは自分でも気づいているがどうしてもやめられない。
791デフォルトの名無しさん:2008/05/15(木) 15:08:56
Java も使うけど、C++ の方が楽に感じる事多いな。
気を付けないと保守が大変というのはわかる。
ただ、どの言語でも保守の問題はあるし、気を付ければ
そんなに問題ないと思ってるけど。まぁ、5年後になんて
言っているかはわからんが。
792デフォルトの名無しさん:2008/05/15(木) 15:57:49
C++の全機能を使わなければならない、という規約でもあったのだろうか?
演算子オーバロードは危険だと思ったなら、単にその機能を使わなければよい。
参照は不要でポインタがあれば十分だと思ったなら、単にその機能を使わなければよい。
添え字が範囲の中にあるかテストしてほしいと思ったなら、at()メンバ関数を使えばよい。

なぜ、C++の全機能 vs Cの比較なんだろう?
C+α(Better C) vs Cの比較をしないのはなぜだ?

要するに、マヌケだってことだ。
793デフォルトの名無しさん:2008/05/15(木) 16:00:18
>>784のリンク先

C++に過剰に複雑なところがあるのは同意なので、
その人(翻訳者でなく)がC++嫌ですって言うこと自体に批判は特に無いけど、
ちょっとツッコミ書くてst。

>C の方を使いたくなる
別に複雑な機能を使わなくても、
 ・#defineマクロ(MAXなど)の代わり程度のtemplate
 ・fopen,fcloseみたいなのをRAIIに扱うための極薄ラッパー
などの簡単で便利なものだけ「better C+おまけ」程度に使えば良いと思う。
巧みで知識もあると言う割には、要領が悪い気がしないでもない。

>Java や Groovy に
そこでGroovyは無いと思う・・・

俺もjava好きだから良いんだけど、
もうちょっと他の言語も挙げれば良いのに・・・
794デフォルトの名無しさん:2008/05/15(木) 16:17:12
>そこでGroovyは無いと思う・・・
ググったら実質両方Javaでワロタw
795デフォルトの名無しさん:2008/05/15(木) 16:22:57
>>792
> C+α(Better C) vs Cの比較をしないのはなぜだ?
自分一人で遊んでいるときしか、そういう使い方がうまくいかないからでは。
796デフォルトの名無しさん:2008/05/15(木) 20:19:22
なぜ今更そのネタを
797デフォルトの名無しさん:2008/05/15(木) 21:02:02
>>792
> C++の全機能を使わなければならない、という規約でもあったのだろうか?
あるとしたら逆だろう。○○しか使ってはいけない、という規約が無くてカオス化する。
あるいは、そういう規約がちゃんと機能して、自分の仕事がうまくいっているとしても、
「ここまでの規約が無ければ収拾つかなくなるC++って・・・」という虚しさは感じることになる。

「C++に文句を言う奴は、C++を使い切れないマヌケだけ」
というのは、C++信者の反撃としては割とお約束だし、部分的には当たっている。
実際、「一人でちょっとしたものを作ることさえできない」人間の八つ当たりも結構見られるし。
ただ、C++の難点というのは、主に「個人の能力ではどうにもならないところ」に表れるものであって、
この話を個人の能力に全部収めて着地させようというのは、わかっててやってるなら
いかにも姑息な「問題のすり替え」ではある。
798デフォルトの名無しさん:2008/05/15(木) 21:14:38
> 個人の能力ではどうにもならないところ
ってどこだろう
799デフォルトの名無しさん:2008/05/15(木) 21:19:29
他人の脳味噌は自分の脳味噌ではない、という事実とか、
そういう風にして複数の脳味噌によって構築された「すんげえ規模」とか。
800デフォルトの名無しさん:2008/05/15(木) 21:21:47
名前マングリングとかABIとかじゃね
801デフォルトの名無しさん:2008/05/15(木) 21:37:50
C++最高!とまでは言わないが、ハードと離れた言語は使う気しないな
802デフォルトの名無しさん:2008/05/15(木) 21:39:21
>>799
それはC++に限った話じゃないな
CでもJavaでもPHPでもよくある話だ

>>800
ABIが規定されていてうまく機能している言語ってあります?

ちなみに、自分はC++信者なわけではない
素直な感想と疑問
803デフォルトの名無しさん:2008/05/15(木) 22:46:45
>>797
どの言語でも仕事で coding する時は文法的に正しければなんでも良い
なんてことは無いはずだが。規約を全く無くせば収拾つかなくなると思うが。
規約を決めるのを C++ に限ったことではない。

元の記事はむしろ binary の compatibility を問題にしてるんじゃないかな。
804デフォルトの名無しさん:2008/05/15(木) 23:05:02
>>802-803
「有るか無いかでいったら、どの言語にだってあるぞ」
というのは確かにその通りだけど、この場合はC++の「度合いのひどさ」を問題にしているわけで、
ゼロじゃないからどの言語もみんな仲間! ってのは、話の持って行き方としてちょっと違うと思う。
805デフォルトの名無しさん:2008/05/15(木) 23:15:56
>>804
でもJavaぐらいだと>>799の問題は似たようなものな気がするけど
だんだん複雑になってきてるし
ある程度表現力が高い言語になると普遍的な問題じゃないかな

C++だとまともに書けない人でもJavaなら書けるのだろうか
そんな人がPythonならまともに書けるのか?
806デフォルトの名無しさん:2008/05/15(木) 23:39:39
規模の問題はちょっと違うだろうね。

名前マングリングに関しては確かにC++のは委員会とかの人も
普通に「どうにかしたい」って思ってそうだけど、
実質、ABIがさえ合えば問題無し、って程簡単じゃないから
再コンパイルした方が良い。

UNIX、Linux系ではオプションの変更程度で再makeすることも多いし。
それに完全にバイナリで使うなら.soとか.dllで考え方が良い。
807デフォルトの名無しさん:2008/05/15(木) 23:46:07
例外とか this ポインタの実装手段の違いとかも問題になるんじゃね。
808デフォルトの名無しさん:2008/05/16(金) 00:27:21
>>797 で言っている問題で、何でも使うか使わないかは、
compile し直そうが残る問題が多いけど。特に保守性考えると。

件の ABI の問題は compile し直せばいい問題じゃないの?
(だから問題になりえないと言っているわけではないが)

ちょっと違うことを問題にしていて議論が混ざってる気がする。

809デフォルトの名無しさん:2008/05/16(金) 21:20:35
質問があります

代入演算子をprotectedないしprivateにしたいんですが、
実装はデフォルトで生成されるものそのままでいいんです

class Hoge
{
 // さまざまなメンバ変数(代入演算子があったりなかったりする)
 Hage hage;
 Fuga fuga;
 int hensuu;
protected:
 Hoge& operator=(const Hoge&);
};

ってやったらリンクエラーになるんですがどうすればいいでしょう
イチイチ中身書くのも面倒で・・・
810デフォルトの名無しさん:2008/05/16(金) 22:07:43
イチイチ中身書くしかない
811デフォルトの名無しさん:2008/05/16(金) 23:25:47
C++0x では default キーワードでデフォルト実装を作ってくれるそうです。
812デフォルトの名無しさん:2008/05/16(金) 23:26:25
handle-bodyイディオムで書いて、handleの代入演算子をprotectedなりにすればどう?
813デフォルトの名無しさん:2008/05/17(土) 01:09:30
バイナリとしての0x00をchar配列に格納したいんですが、終端文字として認識されてしまいます。
こういう時ってどうすればいいのでしょうか??
ご教示いただけると幸いです。
814デフォルトの名無しさん:2008/05/17(土) 01:16:56
もしかしてstrcpyとか使ってるのか?
815デフォルトの名無しさん:2008/05/17(土) 01:21:39
レスどもです。
いえ、const char [] 型に0x00を含む文字列を格納して、cout とかで出力しようとすると0x00以降が出力されないんです。
816デフォルトの名無しさん:2008/05/17(土) 01:22:37
考えるだけでも恐ろしい
817デフォルトの名無しさん:2008/05/17(土) 01:22:59
それは当たり前 仕様 0は文末というのが原則です。
818デフォルトの名無しさん:2008/05/17(土) 01:24:21
出力させたいんだったら、string使えば出来るはず。 こっちはサイズまではちゃんと出力したと思う。
たとえばstr.resize(10000,'\0'); cout<<str;とする。
819デフォルトの名無しさん:2008/05/17(土) 01:24:53
とすると、バイナリとしての0x00を途中に含むchar文字列を作りたいんですが、無理なんでしょうか??
820デフォルトの名無しさん:2008/05/17(土) 01:25:58
0を含むchar配列はできるよ でもstrlenとかは間違える 自分で長さを管理すればよい。
821デフォルトの名無しさん:2008/05/17(土) 01:27:56
たとええばchar配列で0を含まないならstrcpy、strcmpなどを使い、
0を含むなら長さを自分で指定するmemcpyやmemcmpを使う。
822デフォルトの名無しさん:2008/05/17(土) 01:28:55
いや作れるよ
char配列の内容がNTCSであることを仮定している関数・APIに
NTCSでないchar配列を突っ込んでいることが間違いなだけ
823デフォルトの名無しさん:2008/05/17(土) 01:47:42
なるほど!
0x00を入れると格納はされているけど出力できていなかったということですね。
長さを指定したら出力できました。
レス下さった方々ありがとうございましたm(_ _)m
824デフォルトの名無しさん:2008/05/18(日) 02:40:02
質問です。
目標は,動画編集アプリケーションの作成です。
C++(C++/CLI win32api), VC++, C#, Java
の中なら,どれを選択すべきでしょうか?
(ちなみに,上記4つと、C,PHP, JSP/Servletの基礎は習得致しました。)
825デフォルトの名無しさん:2008/05/18(日) 02:44:46
>>824
まずJavaが消えるでしょう
826デフォルトの名無しさん:2008/05/18(日) 02:51:19
C# か C++ でいいんじゃね。
827デフォルトの名無しさん:2008/05/18(日) 02:55:09
不特定多数のユーザーを想定すると .NET をインストールさせるのは気が引けるよね
828デフォルトの名無しさん:2008/05/18(日) 02:59:26
いつまでXP使ってるんだよ。
829デフォルトの名無しさん:2008/05/18(日) 03:01:01
企業では2000が余裕で現役ですよ
830824:2008/05/18(日) 03:03:26
求人情報で、よく"C++経験者歓迎"と書かれています。
この"C++"とは、VC or C++Builder どっちを指しているのでしょうか?

C++で動画編集アプリケーション作成する場合、参考になる本はありますか?
ご教授お願いします
831デフォルトの名無しさん:2008/05/18(日) 03:05:32
どっちでもいいんじゃね
経験者歓迎っつうのは仕事で使った事あるかという事だが
832デフォルトの名無しさん:2008/05/18(日) 03:46:19
ターゲット環境は Windows そうだから DirectDraw について勉強しよう
833824:2008/05/18(日) 04:07:35
>>825
>>826
>>827
>>831
>>832
さん。ありがとうございました。

まず、DirectXの勉強をいたします。。
もし、オススメの本をご存知なら、教えてください。
お願いいたします。
現段階で私が選らんだ本は、
マスタリングDirectXプログラミング
DirectX ゲームグラフィックス プログラミング Ver. 2.1 Vista
です。
834デフォルトの名無しさん:2008/05/18(日) 09:53:45
DirectX関連のスレで聞いた方がよくない?
動画編集といいつつ、実はニコ動投稿用を想定してるとかなら、C#で十分な気も。
プログラミングの勉強という意味ならC++でいいと思うけど。
835デフォルトの名無しさん:2008/05/18(日) 11:41:49
>>832
DirectShow だっしょ
836デフォルトの名無しさん:2008/05/18(日) 13:22:19
=演算子をオーバーロードして、その中でデフォルトの=(オーバーロードしていないときの=)を使うことはできますか?
cClass &operator = (const cClass &a)
{
ここでデフォルトの「=」を使いたい!




}
837デフォルトの名無しさん:2008/05/18(日) 13:37:23
自分で定義しちゃうと
デフォルトの = が定義されないから
無理やね。残念ながら。
838デフォルトの名無しさん:2008/05/18(日) 13:51:00
>>837
ありがとう
839824:2008/05/18(日) 14:24:49
>>834
レス、ありがとうございます。
今回は,ニコ動投稿を考えていません。
(ただ,面白そうなので,そのうちアプリケーションに追加したいと思ってます)
主に,プログラミングの勉強です。

>>835
!!!
ありがとうございます。
現時点では,洋書はすらすらと読めません。
そのため,和書のDirectX本でDirectXの基礎を勉強する。
それから,英語・DirectShowの勉強を始めます。

皆さん,本当にありがとうございました。
840デフォルトの名無しさん:2008/05/18(日) 15:02:38
DirectShow はネット上の情報が少ないから頑張れ。
841デフォルトの名無しさん:2008/05/18(日) 15:14:15
DirectShowと戦うスレってPart 3の後立ってないんだな。
Part4立てちゃってもいいかも。
842デフォルトの名無しさん:2008/05/18(日) 20:18:01
>>835
おお、そうだった
自分も苦労したのに、もう忘れてる
843デフォルトの名無しさん:2008/05/18(日) 20:49:57
>>841
part3は半月もせずに落ちたんだな
844デフォルトの名無しさん:2008/05/18(日) 23:43:45
DirectShowはMSDNに超詳しく載ってるだろ
要はCOMなので分かってればそうそう難しくもない
845デフォルトの名無しさん:2008/05/18(日) 23:49:08
COMこわいよ
あー頭が割れるくぉおおぉぉx

COMがぁCOMがぁ襲ってくるよぉ

ハァハァハァ
846デフォルトの名無しさん:2008/05/19(月) 00:13:38
MinGWを使っているのですが、int型の10をstring型オブジェクトに変換すると、データがおかしくなりませんか??

string s;
s = 10;
ofstream fout("test.txt");
fout << s;

このプログラムで出力したtest.txtをバイナリエディタで見てみると、
0x0D 0x0A
となっています。0x0Dってのはなんなのでしょう。

11の時はちゃんと0x0Bだけになっているし、20の時はちゃんと0x14だけになっています。
なぜか10の時だけ0x0Dが付加されてます。
847デフォルトの名無しさん:2008/05/19(月) 00:16:14
変・・・換・・・?
848デフォルトの名無しさん:2008/05/19(月) 00:28:20
ファイルをテキストモードで開いてるときは、\n(0A) → \r\n(0D 0A) に変換される
バイナリモードで開けばおk
849デフォルトの名無しさん:2008/05/19(月) 00:34:46
> s = 10;
まずここが間違い。
stringstreamを使うこと。
850846:2008/05/19(月) 00:40:40
なるほどっ。。テキストモードで開いているせいだったんですね。。
ありがとうございましたm(_ _)m

すいませんついでにもう1つ教えていただきたいのですが、
string s;
s = 20;
ofstream("test.txt");
fout << s;

のような感じにすると、バイナリの0x14がちゃんと出力されるので
string型オブジェクト = int型の値
の代入で、うまいぐあいにstring型に変換してくれるのだと思っていたのですが、
ふと2バイト以上必要な数値はどうなるのだろうと思って
s = 512;
fout << s;
のようにしてみると、0x00が出力されてしまいました。
2バイト以上必要な数値でもうまくstring型のオブジェクトに格納するにはどのようにすればよいのでしょうか??
アドバイスいただけると幸いです。
851846:2008/05/19(月) 00:44:27
>>849
すいませんリロードしないで書き込んでました。

stringstream ss;
ss << (char)20;

のような感じでうまくいきました!ありがとうございましたm(_ _)m
852デフォルトの名無しさん:2008/05/19(月) 00:44:27
stringstreamか,面倒ならboost::lexical_castを
853846:2008/05/19(月) 00:59:41
すいません、解決した・・と思ったのですが、
stringstream ss;
ss << 512;
とすると、stringstreamでも0x00が出力されてしまっていました。

このやり方では2バイト必要な文字の場合は最後の1バイトしか出力されないようなのですが、
stringオブジェクトに 例えば 10進数の513をバイナリの0x01 0x01 と格納したいような時はどうすればよいでしょうか・・

>>852
ありがとうございます。調べてみます。

854846:2008/05/19(月) 01:01:09
×2バイト必要な文字
○2バイト必要な数字

ですね。。度々すいません。
855デフォルトの名無しさん:2008/05/19(月) 01:03:27
> バイナリの0x14がちゃんと出力されるので
それはstring型に変換しているとは言わないと思うんだが・・・。
バイト列を出力したいのか、文字列を出力したいのははっきりさせた方がいい。
文字列なら、例えば10進数で"20" "512"と出力されるだろう。
856デフォルトの名無しさん:2008/05/19(月) 01:05:13
バイト列の出力ならchar*にして、stream.write()で。
857デフォルトの名無しさん:2008/05/19(月) 01:13:35
あと、intとかをバイナリで書き出すなら
ネットワークエンディアン(ビッグエンディアン)とかで出した方が良いと思う。
858デフォルトの名無しさん:2008/05/19(月) 08:35:42
エンディアンを問わないなら、
int i = 513;
ofstream fout("result.bin", ios::binary);
fout.write((char*)&i, sizeof(i));
たぶんこんな感じ(テストしてないから間違ってるかも、あと環境依存がある)。
859デフォルトの名無しさん:2008/05/20(火) 09:38:31
string s = 20 っていう初期化はコンパイルエラーになるけど、宣言した後の
s = 20 っていう代入はエラーにならないんだな。この代入演算子は危ないだけのような
気がする。 char 1文字にしたけりゃ assign() 使えばいいし。
860デフォルトの名無しさん:2008/05/20(火) 10:14:18
>>859
それって、stringクラスにint型からの型変換は定義されてないけど、
int型の代入演算子は定義されてる、ってこと?
861デフォルトの名無しさん:2008/05/20(火) 10:25:07
>>860
char 型を受け取る代入演算子に int が食われてる。
862デフォルトの名無しさん:2008/05/20(火) 10:44:14
>>859
g++ -Wall してみたけど、そうだね。

string s(20);
string s=20;

はだめで

string s; s=20; は warning 無しで OKってのは紛らわしい。

ついでに入ってるは DC4 とかだし。
863デフォルトの名無しさん:2008/05/20(火) 11:01:48
これだから型付け緩いクソ言語は
864デフォルトの名無しさん:2008/05/20(火) 11:09:12
>>863 C++ は自分を律せない人には使えない言語。
865デフォルトの名無しさん:2008/05/20(火) 11:10:22
boost無しでは使いたくない事だけは確か
866デフォルトの名無しさん:2008/05/20(火) 12:49:46
結局、ヘタしたらソースまで読んで、
細かいクラスの実装まで理解しないとプログラムできないのか・・・

オブジェクト指向って、そう言うことしなくても
プログラムできるのがウリじゃなかった?
867デフォルトの名無しさん:2008/05/20(火) 13:05:35
>>866
> オブジェクト指向って、そう言うことしなくても
> プログラムできるのがウリじゃなかった?

ちゃんとドキュメントがあれば問題はない。

868デフォルトの名無しさん:2008/05/20(火) 13:09:43
Visual C++ では string オブジェクトに int を代入しようとするとエラーをはいたように思った。
あと、 stringstream はやめにしてこれからは sstream を使って頂戴って話になってなかったっけ?
869デフォルトの名無しさん:2008/05/20(火) 13:10:34
ドキュメントがないとかオスになるのはどの言語でも一緒だしね。
870デフォルトの名無しさん:2008/05/20(火) 13:52:48
>>866
何が言いたいんだかよくわからん。重箱の隅をつついたような
あいまいなコーディングをせず、安全第一でしなきゃいかんでしょ。

> 結局、ヘタしたらソースまで読んで、
> 細かいクラスの実装まで理解しないとプログラムできないのか・・・

どんな言語でも「ヘタしたらソースまで読んで…」というのは
当てはまると思うけどね。「ヘタしたら」なんだから。
871デフォルトの名無しさん:2008/05/20(火) 17:05:23
どんなに頑張っても絶対にヘタをすることのできない
夢の言語と比較しての批判でしょう、たぶん。
872デフォルトの名無しさん:2008/05/20(火) 18:12:46
>>865
仕事で書くソースにboostを使いたくない事だけは確か。
少なくとも俺はね・・・。

>>866
そういうウリは無いよ。

>>868
strstreamは使うな、の間違いじゃね?
sstreamはstringstream使うときにincludeするファイル名だよ。
873デフォルトの名無しさん:2008/05/20(火) 19:06:45
boost無しでは使いたくないっていうのは
10年以上前から欠陥品って言われてるような標準のfunctionalとかstream系のような
欠陥品をそのまま使うなんてありえない、boostで提供される改良版使いたいっていう主張ね

boostって標準ライブラリの欠点を補うようなものも多いし
そういうのなら仕事でもガンガン使えると思うんだけどどうか
874デフォルトの名無しさん:2008/05/20(火) 19:18:24
もう二度とboostのコードレビューはしたくありません。
875デフォルトの名無しさん:2008/05/20(火) 22:31:19
>>845
COM COM たっぷりCOM
876デフォルトの名無しさん:2008/05/20(火) 22:57:06
C++って正直覚えることが多すぎてちょっと疲れたよ
他の言語で書いて速さが必要な箇所だけC++で書けばそれでいいんじゃなかろうか
877デフォルトの名無しさん:2008/05/20(火) 23:02:35
それでいいんじゃないすか
Cと違って他言語から呼び出すのは難しいけど

Win限定ならC#でGUI書いてキツイ所はC++/CLIとかできるし
878デフォルトの名無しさん:2008/05/20(火) 23:02:53
>>876
C++ は全部を知ろうと思ったら大変だよ。C 全ても含まれるし
かなり重複がある。それでついでに STL+boost 位は必要。
ただ、それ全てを知る必要は無いけどな。
879デフォルトの名無しさん:2008/05/20(火) 23:13:20
boostはまだ標準じゃないから勉強は後回しでいいよね?
MFCとATL覚えるのに手一杯でさ・・・
880846:2008/05/20(火) 23:14:47
色々アドバイスありがとうございました!

fout.write((char*)&i, sizeof(i));
これでうまく行きました。

スタンダードMIDIファイルを吐くプログラムを作ってて、ビックエンディアンで並べないといけないところがあったのですが
ss << p[3] << p[2] << p[1] << p[0];
みたいな感じで書いてなんとかなりました。

ありがとうございましたm(_ _)m
881デフォルトの名無しさん:2008/05/20(火) 23:21:53
>>879
boost は便利なものがあるから、あることを知っていて何か
「これはあるべきだけど無い!」みたいなものがあったときに
探すと良いと思う。かなりの確率である。

boost 全てについて学ぼうなんて考えない方が良い。
882デフォルトの名無しさん:2008/05/20(火) 23:26:29
>>879
tr1に入った奴位は覚えとけばいいんじゃね
shared_ptrとか便利だよ
883デフォルトの名無しさん:2008/05/20(火) 23:28:10
vaultやsandboxまで手を付けるとキリが無くなるという
884デフォルトの名無しさん:2008/05/20(火) 23:42:47
テンプレートでifとか制御文とか
作ってみたけどなかなかboostまでいかない
どうしてなんだろう
885デフォルトの名無しさん:2008/05/20(火) 23:47:49
boost::anyあたりなら俺でも読めたよ
886デフォルトの名無しさん:2008/05/20(火) 23:54:51
>>884
心配するなって。ものによると思うよ。
自分に必要なものなら、これだ!ってわかるさ。

あと、比較的簡単に入れるのも多い。
ただ、初め何を言ってるのかさーっぱりのもある。
887デフォルトの名無しさん:2008/05/21(水) 00:02:09
いやそうじゃなくて何もみないで
boost:anyの関数名だけみて

oreore:any作ってみたが
全然あっちの方がいけてるって話
発想レベルが腐ってるんだろうな
888デフォルトの名無しさん:2008/05/21(水) 00:04:32
>>887
でも書いてみるってのはいいと思うぞ。
自分でやれば、Boostの実装がいいってのが実感できる。
889デフォルトの名無しさん:2008/05/21(水) 00:05:04
ぱっと見でboostレベルの実装が思いつく奴なんてそういないだろ・・
890デフォルトの名無しさん:2008/05/21(水) 00:08:53
質問です。
コピーコンストラクタで一部の値だけ新しい値を与えてオブジェクトを生成したいのですが、こういう書き方はアリ(普通に使うか)でしょうか?

class Base
{
public:
 Base( int newID, const Base& rhs ) : m_id( newID ), m_param( rhs.m_param ){}
 virtual ~Base(){}
private:
 int m_id;
 int m_param;
};

class Derived : public Base
{
public:
 Derived( int newID, const Derived& rhs ) : Base( newID, static_cast<const Base&>( rhs ) ), m_name( rhs.m_name ){}
 virtual ~Derived(){}
private:
 string m_name;
}
891デフォルトの名無しさん:2008/05/21(水) 00:13:50
それはコピーコンストラクタとは言わないけど、手法としてはありじゃね?
標準ライブラリでもlocaleでそういうことやっている。
892デフォルトの名無しさん:2008/05/21(水) 00:50:38
boostで実装が想像すらできないのがis_base_ofね
親クラスの型なんてどうやってチェックしてんだかさっぱわからん
893デフォルトの名無しさん:2008/05/21(水) 00:54:30
Visual C++なら__is_base_ofを使うだけ。
そのうちどこのコンパイラも似たようなものを用意するに違いない。
894デフォルトの名無しさん:2008/05/21(水) 08:28:05
>893
boostはあらゆる環境で使えるわけだが、
VC++固有の話をしただけじゃ全然わかったことになってないぞ
895デフォルトの名無しさん:2008/05/21(水) 18:20:49
そんな冗談を真に受けるなよ……。
896デフォルトの名無しさん:2008/05/22(木) 13:20:28
C言語ばかりやってきてC++はあまり良く分かっていないんですが、
例外というのは関数の戻り値によるエラー処理と違ってどういうメリットがあるんですか?
なんか例外はBasicのGoto文みたいで流れが読めなくて気持ち悪いんですけど。
897デフォルトの名無しさん:2008/05/22(木) 13:37:11
>>896
戻り値の確認を忘れるヘマを避けられる。
あと、戻り値を持たないコンストラクタからも使える。
898デフォルトの名無しさん:2008/05/22(木) 13:39:12
>>896
例えば
int foo() {
 if (bar() == 失敗) return 失敗;
 if (baz() == 失敗) return 失敗;
 if (hoge() == 失敗) return 失敗;
 return 成功;
}
のようなものを
void foo() {
 bar();
 baz();
 hoge();
}
と書いて失敗を例外で投げればコードが簡潔
あとコンストラクタなどの戻り値を取れない関数でエラーを返すのに使ったり使わなかったり
899デフォルトの名無しさん:2008/05/22(木) 13:42:21
>>897
「コンストラクタから例外を投げるな!」
って、どこかで聞いた気がするけど、そうでもないのか?
900デフォルトの名無しさん:2008/05/22(木) 13:46:57
>>899
「デストラクタから例外を投げるな!」
の間違いでは?
901デフォルトの名無しさん:2008/05/22(木) 13:49:14
>>899
例外安全を心掛けないと資源リークする可能性がやや上がるというだけ。
deleteとかを生で使うな、auto_ptr/shared_ptrとかvectorとかを使え、で大体済む話。
902デフォルトの名無しさん:2008/05/22(木) 14:02:32
[迷信] コンストラクタから例外を送出してはならない
ttp://www.kijineko.co.jp/tech/superstitions/dont-throw-exception-from-constructor.html
903デフォルトの名無しさん:2008/05/22(木) 14:15:29
都市伝説が多い言語?
904デフォルトの名無しさん:2008/05/22(木) 16:11:34
>>902の次のようにしますってのもよい例には見えない。
まずfunction-try-catch使うとか、throw;書くとかして例外を投げなおせよ。
905デフォルトの名無しさん:2008/05/22(木) 16:18:54
まぁ、確かに良い例じゃないね。
普通は↓だし。

struct foo {
    std::auto_ptr<A> a;
    std::auto_ptr<B> b;
    foo() : a(new A), b(new B){
        ...
    }
};
906デフォルトの名無しさん:2008/05/22(木) 17:30:52
RAIIを徹底してればどこから例外が出ようと問題ないので
処理の流れとか気にしなくても良い
907デフォルトの名無しさん:2008/05/22(木) 22:05:15
コンストラクタで例外が出る可能性のある処理を書くのが間違いなんじゃないの?
908デフォルトの名無しさん:2008/05/22(木) 22:25:44
それは、状況次第。

コンストラクタで例外を発生させないためだけに、コンストラクタと
それに続く処理を分けたメソッドを作るのは、俺はダサいと思う。
909デフォルトの名無しさん:2008/05/22(木) 22:35:00
ばーかwwwwwwwwww
910デフォルトの名無しさん:2008/05/22(木) 22:36:59
ここのメモリアロケーションの速度比較で
ttp://shinh.skr.jp/loki/SmallObj.html

MemoryPoolのBigObject Class FがUseMemoryPool<C, 4000>を継承していますが
UseMemoryPool<F>でなくても良いんでしょうか?
911デフォルトの名無しさん:2008/05/22(木) 22:37:59
つうかRAIIしようと思ったらコンストラクタでの例外は避けられないだろ
絶対に確保に失敗しないリソースがあるなら別だけど
912デフォルトの名無しさん:2008/05/22(木) 22:47:36
質問です(gcc 4.1.1)。ログを出力する簡単なクラスを作ろうと思い、
出力ストリーム(std::ostream &)またはファイル名(const char *)
を引数に取るコンストラクタを作りたいのですが、どうやるのが一番スマートでしょうか?
とりあえず以下のようにしてみたのですが、
class Logger {
private:
 std::ostream *logOs;
public:
 Logger(std::ostream &os = std::cout): logOs(&os) {}
 Logger(const char *file): logOs(new std::ofstream(file)) {
  if (!*logOs) { /* エラー処理 */ }
 }
 ~Logger() { delete logOs; }
};

これでは不十分で、コンストラクタの引数が出力ストリームのときは
デストラクタでlogOsをdeleteしないようにする処理も必要です(ダサい)。
また、デストラクタでdeleteすること自体もできればやめたいです。
そのためにはlogOsをポインタではなくstd::ostream自身にする必要があると思い、まず
class Logger {
private:
 std::ostream logOs;
public:
 Logger(std::ostream &os = std::cout): logOs(os) {}
};

とだけ書いてみたところ、以下のようなエラー(他にも色々)が出ました。
が、意味が分かりません。orz
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/ios_base.h:779: error: 'std::ios_base::ios_base(const std::ios_base&)' is private
グダグダと書いてしまいましたが、何かアドバイスがあればお願いします。
913デフォルトの名無しさん:2008/05/22(木) 23:07:04
>>912
エラーの内容は、「std::ostreamのコピーコンストラクタは使用が禁止されているからlogOs(os)はできないよ」
前者のクラスの設計について思ったんだが、一つ目のコンストラクタではクラス外からオブジェクトを持ってきているのに
二つ目ではクラス内で完結していて、しかもデストラクタでdeleteしている。何故こんなに中途半端なのか?という疑問。
クラスを横断するオブジェクトを保持したいのならauto_ptrなりshared_ptrなりを使えば良いし、
そうでないならクラス内でヒープから持ってくるオブジェクトも完結させる。
914デフォルトの名無しさん:2008/05/22(木) 23:15:21
>>912
直前で散々話題になってるのに・・・w
生のdelete使うなw

>どうやるのが一番スマートでしょうか?
まず、スマートポインタを使う。

俺ならファイル名貰うコンストラクタなんて作らない。
std::ostream&か、std::auto_ptr<std::ostream>を貰う。
915デフォルトの名無しさん:2008/05/22(木) 23:15:58
>>912
class Logger {
std::ostream * pOs;
std::ostream & rOs;
public:
Logger(std::ostream & os) : pOs(NULL), rOs(os) {}
Logger(const char * file) : pOs(new std::ofstream(file)), rOs(*pOs) {}
~Logger() { delete pOs; }
};

とりあえずオリジナルのLoggerを尊重してみた。
ただ何かイマイチだね。うまく言えないけど。
916デフォルトの名無しさん:2008/05/22(木) 23:21:01
そんなにスマートポインタいいかなあ
917デフォルトの名無しさん:2008/05/22(木) 23:23:36
RAIIを使わないC++はC++じゃない、くらいに考えても良い
918デフォルトの名無しさん:2008/05/22(木) 23:26:19
>>915
delete するかどうかのフラグを持ったスマートポインタを使えばいいのさ。
919デフォルトの名無しさん:2008/05/22(木) 23:32:09
スマートさを追求したいならconst char *のコンストラクタない方がいいんじゃね?と
ここまで読んで思った。
ostreamのポインタってすごく気持ち悪いの俺だけ?
920912:2008/05/23(金) 01:03:31
色々とアドバイスありがとうございます。
>>913
エラーの意味は分かりました。禁止されている理由については以下を読んで何となく分かりました。
http://imt.uni-paderborn.de/download/solaris/Sun_Studio_11/CD1/kits/ide/packages/SPJAhtstd/reloc/SUNWspro/prod/lib/locale/ja/html/manuals/stdlib/user_guide/loc_io/13_2.htm
後半はちょっと意味が分かりませんでした。orz

>>914, 919
確かにストリームに加えてファイル名まで指定可能にするというのは欲張りというか、
綺麗な設計ではないのかもしれません。ストリームのみ指定可能とすればよいなら
std::ostream &logOsで簡単に実現可能なんですよね。
std::ostream *は私も気持ち悪いです。
921912:2008/05/23(金) 01:12:50
>>915
なるほどです。あとは >>914 さんが指摘しているように、
pOsをスマートポインタにすれば今のところ最もスマートな方法だと思います。
ストリームとファイル名の両方を指定可能にするには、
std::ostream * の使用は避けられないのかもしれません。
922デフォルトの名無しさん:2008/05/23(金) 01:30:40
>>916
「そんなに」ってどういうこと?
最低限の auto_ptr を使うだけでも何か引き換えにするものがあるとでも言うの?
923デフォルトの名無しさん:2008/05/23(金) 11:00:27
これでどうよ

class Logger {
std::ostream & rOs;
public:
Logger(std::ostream & os) : rOs(os) {}
};
class FileLogger: public Logger {
std::ofstream ofs;
public:
FileLogger(const char * file) : Logger(ofs), ofs(file) {}
};
924デフォルトの名無しさん:2008/05/23(金) 13:15:00
大きいサイズのメモリを確保するとき、
タスクマネージャーの空き容量より小さい値でも確保できないときがあります。
これは、メモリの断片化などで連続領域が確保できない。
ということでよろしいのでしょうか?
また、これを回避して大容量の連続領域を確保する方法はあるのでしょうか?
ちなみに、空き容量1.9GBで500MBの連続領域が確保できませんでした。
確保の関数はnewを使っています。
よろしくお願いします。
925デフォルトの名無しさん:2008/05/23(金) 13:25:43
プロセス内のメモリ空間が断片化するほど、確保と解放してるの?
仮想記憶だからプロセス間での断片化は関係ないはずだが。
926デフォルトの名無しさん:2008/05/23(金) 14:01:07
ヒープの上限が低く設定されているんだよ
VC6ならプロジェクトオプションに /Zm何たら と指定すればいいんだ
僕は頭が悪いのにC++を使っているよ
927912:2008/05/23(金) 14:55:06
>>923
なるほど、継承を使ってostream &とofstreamを組み合わせるわけですね。
で、>>915 と見比べながら考えていたら、
継承を使わなくても実現できるのではと思い、
class Logger {
 std::ofstream ofs;
 std::ostream &rOs;
public:
 Logger(std::ostream &os): ofs(0), rOs(os) {}
 Logger(const char *file): ofs(file), rOs(ofs) {}
};
としたところ、これでも動きました!
なぜ >>915 を見たときに思いつかなかったんだろう?
ostreamとofstreamを混在させるという発想がなかった
のかもしれません。
ちなみにofsとrOsの宣言の順番を逆にしても、つまり初期化子を
rOs(ofs), ofs(file) としても動きました。ちょっと不思議です。
928デフォルトの名無しさん:2008/05/23(金) 14:57:18
>>926は問題外として、その環境じゃ確保できないんだろう
C++の問題というわけではないので、環境依存スレで聞いた方が良いよ

XPだと標準設定で512MBまでは確保できたと思うが、レジストリの値とか確認してみると良い
929デフォルトの名無しさん:2008/05/23(金) 15:04:59
>>927
メンバ変数は宣言した順に初期化される。
初期化子の順番は関係ない。
930デフォルトの名無しさん:2008/05/23(金) 15:43:40
templateな関数で文字列をtemplateとして使いたいんですができますか?

template< const char* T >
void basic_test( const char* test )
{
puts( T ); // ファイル名
puts( test ); // 書き込み

}

int _tmain(int argc, _TCHAR* argv[])
{
basic_test< "test.log" >( "test" );
return 0;
}

こんな感じで使いたい
931デフォルトの名無しさん:2008/05/23(金) 15:51:20
やってみて出来たなら、君の環境では出来るということだろう。
932デフォルトの名無しさん:2008/05/23(金) 16:10:35
>>925
>>926
>>928
回答ありがとうございました。
環境依存スレでも質問してみたいと思います。
933デフォルトの名無しさん:2008/05/23(金) 16:29:23
>>931
できませんでした
934912:2008/05/23(金) 16:43:25
>>929
失礼、説明不足でした。
ofsとrOsの変数宣言の順番と初期化子の順番の両方を逆にしても
動いたということです。つまりrOs→ofsの順番にした場合、
Logger(const char *file): rOs(ofs), ofs(file) {}
というコンストラクタにおいて、rOs(ofs)が先に実行されるはずですが、
ofsが初期化されていないのに実行できるのかという疑問があります。
もしかすると、初期化における代入の依存関係を見て
ofsが先に初期化されたりするんでしょうか。
935デフォルトの名無しさん:2008/05/23(金) 17:15:23
>>934
初期化リストの並びは初期化の順番に関係ない
あくまでもメンバ変数の宣言順に実行される
936デフォルトの名無しさん:2008/05/23(金) 18:14:59
>>935
ちゃんと読んでやれよ・・・w

>>934
普通に未初期化のまま、ofsの参照が渡ってる。
あまり良くない方法ではあるものの、
未初期化のインスタンスの
メンバにアクセスしなければ問題無い。
なので、そのLoggerの実装なら大丈夫。
937912:2008/05/23(金) 21:12:07
>>936
> 普通に未初期化のまま、ofsの参照が渡ってる。
色々試してみて理解できました。
初期化子においてrOs(ofs)が先に実行される時点では
ofsは存在さえしないと思っていたんですが、存在はしていて、
ただし初期化されていない(=引数なしでコンストラクタが呼ばれてofsが生成された)
状態なんですね。
938デフォルトの名無しさん:2008/05/23(金) 21:37:48
>>937
いや、ofsのコンストラクタは呼ばれてない。
メモリが確保されてるだけ。(アドレスは確定してる)
939デフォルトの名無しさん:2008/05/23(金) 21:40:34
未初期化オブジェクトの参照を取る事って、規格的に許されてるんだっけ?
未定義動作な匂いがプンプンするんだが。
940デフォルトの名無しさん:2008/05/23(金) 21:46:42
参照だけなら多分大丈夫。何か呼び出したりしたらアウト。
キモイから俺は参照もしないけど。
941デフォルトの名無しさん:2008/05/23(金) 22:01:38
未初期化で触るのが嫌ならboost::base_from_memberでも使えばよい。
というか折角分離したのに何故わざわざくっつけるんだ?>>927
942912:2008/05/23(金) 22:03:38
>>938
なるほど、そういうことですか。
それなら処理時間のオーバーヘッドもほとんどないですね。とはいえ、
>>940
確かにキモいので私も実際にはofs→rOsの順番にしときますが。
943デフォルトの名無しさん:2008/05/23(金) 23:12:21
>>941
>というか折角分離したのに
あ、俺もそれ思ったw
944912:2008/05/24(土) 10:51:36
一つのクラスにまとめた理由は、ストリーム、ファイルの場合とも
ファイル名を引数にとるコンストラクタ以外のインタフェース(メソッド関数)
が実装を含めて同じだからです。
逆に分離した場合、FileLoggerの方で記述されるのは
・メソッド変数ofsの追加
・ファイル名を引数にとるコンストラクタの追加
のみです。これだけのために分離するメリットを感じませんでした。
一つのクラスにまとめるデメリット、分離するメリットがあれば教えてください。
945デフォルトの名無しさん:2008/05/24(土) 10:58:48
>>944
分離してあればファイル以外の ostream に対しても同じクラスがそのまま使える。
(同じことだけど、)混ぜてあると別の ostream に対して使う場合に ofstream が無駄になる。
946デフォルトの名無しさん:2008/05/24(土) 11:31:21
>>944
ostream
   ofstream
   ostringstream

Logger
   FileLogger
   MemoryLogger

void f1(Logger& log){
  ...
}
void f2(){
  FileLogger log("a.log");
  f1(log);
}
void f3(){
  MemoryLogger log;
  f1(log);
}
947デフォルトの名無しさん:2008/05/24(土) 11:41:29
>>944
標準出力だろうがファイル出力だろうがstring型の変数への出力だろうが
もっと極端なこと言えばFTPでファイルうpする処理だろうが、
何かを出力する処理ならばostreamに対応した処理を1回書けばいい、
っていうのがostreamの理念。

その関数を呼ぶ側であらかじめ出力したい対象に対応する
ostream(の派生クラス)を勝手に作っておいて、
osteream対応関数を呼び出せば、
あとはostream(の派生クラス)が良きに計らって
実際の出力対象に出力してくれてる。
948912:2008/05/24(土) 11:46:19
なるほど、メモリなど様々な種類のものに対応するために拡張しようとしたとき、
一つのクラスにまとめているとムダなメンバ変数がどんどん増えてしまう
(もしかするとメンバ変数も増えるかも)ので、クラスを分類しておく方が
いいわけですね。
(LoggerとFileLoggerだけを例にとってもofstreamがムダになってる。)
949デフォルトの名無しさん:2008/05/24(土) 11:50:36
なんだかんだで理解できてるのは良いね。
950912:2008/05/24(土) 11:55:17
>>947
ん?そう考えていくと、ostream自身にログを出力するメンバ関数を
追加したくなってきますね。そうすればofstreamでもstringstreamでも
そのログ出力関数をそのまま使えるし。
(つまりFileLogger, StringLoggerのような派生クラスを作る必要がない。)
そういう考えって変?
# 変じゃないとしても、実現方法が分からない…。
951デフォルトの名無しさん:2008/05/24(土) 12:08:09
自作クラスにstreamのインターフェースを搭載するのにboostって使える?
952デフォルトの名無しさん:2008/05/24(土) 12:12:33
>>950
うん、正直なくてもいいと思う。
Loggerを"利用する側"でファイルに出力して欲しいなーと思ったときは
std::ofstream ofs(filename);
Logger logger(ofs);
すればいい。

Logger側で何に出力してるかを気にする必要がなくなる。
953デフォルトの名無しさん:2008/05/24(土) 12:29:07
出力するだけなら生でもいいけど、対象特有の加工をしたかったら
やはり派生してメンバを追加したくなるな。
FileLoggerに最大出力行数を設定して行が溢れたら自動的に
ログファイルの先頭から削除とか。
実際にするかどうかはともかく、将来の拡張に柔軟というのは
考慮に値する特性だと思う。
954デフォルトの名無しさん:2008/05/24(土) 12:35:34
>>950
役割を考えるとそれはちょっと違うかな。
ofstreamはストリームで、ログはストリームとは限らないだろう?

ログを出力先はファイルでもメモリでもなく、
システムに用意された関数かもしれない。

Loggerの役割は、ログを出すこと。
ostreamに出力するのも、ログ出力の実装の一例に過ぎないと考えた方がいい。
955デフォルトの名無しさん:2008/05/24(土) 13:59:48
コンストラクタ内から、他のクラスなどに対して this ポインタを渡す、ということは可能でしょうか
956デフォルトの名無しさん:2008/05/24(土) 17:23:55
可能。やってみればわかる。注意事項はイロイロあると思うけど。
957912:2008/05/24(土) 18:01:44
Rubyとかだと既存クラスに簡単にメソッドを追加できるので
>>950のような発想をしたんですが、
基本的には>>952のような方法で利用すれば十分ですよね。
と考えると、>>927 のようにファイル名を引数にとるコンストラクタまで
用意するのは車輪の再発明っぽくてあまり美しくないなあと思いました。

>>953,954
ログ出力の実装をostreamの派生クラスによって変えたいかもしれない、
ログ出力の適用先がostream以外にもあるかもしれない、ということですね。
参考になりました。
958デフォルトの名無しさん:2008/05/24(土) 18:20:45
>>951
Boost.Iostreamsがある。
http://www.boost.org/doc/libs/1_35_0/libs/iostreams/doc/tutorial/container_sink.html
write()関数と、適切なtypedef2つ(もしくは継承)で書き込みストリームが出来上がる。

読み取りストリームもほぼ同じ感じ。
959デフォルトの名無しさん:2008/05/24(土) 19:51:07
>>956
返信ありがとうございます
Javaで駄目だと言われていたので気にしていたのですが…
注意事項というのは、コンストラクタ抜ける前にポインタを使われたりすると問題が起きる、といったようなものですか?
960デフォルトの名無しさん:2008/05/24(土) 20:25:51
>>959
Javaで駄目だというのも同じ理由。
初期化が完了していないため、
そのオブジェクトのメソッド(C++ではメンバ関数)などを呼ぶと
予期せぬ状態になる。

逆にいえば、JavaでもC++でも、そのオブジェクトを扱わずに
ポインタ(or参照)を保存するだけに留めるなら問題無い。

ちなみに >>936-940n で同じ話が。
961デフォルトの名無しさん:2008/05/24(土) 23:36:57
アンチ C++ で有名な人ってどんな人がいますか?
962デフォルトの名無しさん:2008/05/24(土) 23:43:46
>>961
マーセンさん
シーリ・マーセン
963デフォルトの名無しさん:2008/05/24(土) 23:45:02
>>961
ファイン・デュアセルフ
964デフォルトの名無しさん:2008/05/25(日) 00:14:45
ジャバ・ダ・ヤッパ
965デフォルトの名無しさん:2008/05/25(日) 00:20:10
>>961
モーツァルト
966デフォルトの名無しさん:2008/05/25(日) 00:23:45
C#が好きって言いたいのか
967デフォルトの名無しさん:2008/05/25(日) 00:27:30
>>961
セルゲイ=ストイコビッチ
968デフォルトの名無しさん:2008/05/25(日) 03:00:46
>>961
禿
969デフォルトの名無しさん:2008/05/25(日) 09:26:50
.net 2003の_com_error& では代入演算子の中でコンストラクタを呼び出してます。

inline _com_error& _com_error::operator=(const _com_error& that) throw()
{
if (this != &that) {
this->_com_error::~_com_error();
this->_com_error::_com_error(that); // ココ
}
return *this;
}

よく複数のコンストラクタで同じ処理をしたい場合、コンストラクタから
別のコンストラクタを呼び出すことはできないから初期化関数を
作ること、とされていますが、上記コードがOKならばコンストラクタから
別のコンストラクタを呼び出してもいいように思えます。
実際.net 2003でやってみましたが、問題なく動作します。msの独自仕様なんでしょうか?
970969:2008/05/25(日) 09:42:46
BCC5.5.1ではthis->があるとビルドエラーになりました。
this->をはずすと上手く動いているように見えます。

テストコードはこんな感じです。
class Cls
{
public:
Cls(void){printf("ctor\n");}
Cls(int i){ Cls::Cls();}//ココ
};

int main(void)
{
Cls c; // ctor
Cls c2(1); // ctor
return 0;
}
971デフォルトの名無しさん:2008/05/25(日) 10:00:03
少なくともbccのほうのコードは、一時オブジェクトが作られて、そのコンストラクタが呼ばれてるだけだと思うけど。
972デフォルトの名無しさん:2008/05/25(日) 10:33:37
>>970
とりあえず、コンストラクタでthisのアドレス出してみたら?
std::cout << "ctor " << this << std::endl;
973デフォルトの名無しさん:2008/05/25(日) 10:43:33
>>970
以下のようにして、thisとkの値をモニタしながらステップ実行してみよう。
class Cls
{
private:
int k;
public:
Cls(void)
{
printf("ctor\n");
}
Cls(int i)
{
k=3;
Cls::Cls();
}//ココ
};
974973:2008/05/25(日) 10:45:22
一行抜けてた
class Cls
{
private:
int k;
public:
Cls(void)
{
k=5;
printf("ctor\n");
}
Cls(int i)
{
k=3;
Cls::Cls();
}//ココ
};

975デフォルトの名無しさん:2008/05/25(日) 10:47:10
>>969
placement newを使う方法ならどのコンパイラでも使える。
#include <new>
T& T::operator =(const T& y)
{
  if (this != &y)
  {
    this->~T();
    new(this) T(y);
  }
  return *this;
}
しかし、コンストラクタの中で例外が起こると非常にまずい
(thisがデストラクタされて状態不定のまま)などの理由で勧められない。

代入演算子をコピーコンストラクタで実装したいという目的に限れば、
Exceptional C++でも紹介されているswapを使う方法がいい。
//その1
T& T::operator =(const T& y)
{
  T t(y);
  swap(t); //Tのメンバ関数として作っておく
  return *this;
}
//その2
T& T::operator =(T y)
{
  swap(y);
  return *this;
}
976デフォルトの名無しさん:2008/05/25(日) 10:54:51
Tのコピーコンストラクトが高コストの場合は↓

T & operator =(const T & t)
{
if(this != &t) {
T(t).swap(*this);
}
return *this;
}
977969:2008/05/25(日) 14:06:49
>>971、972、973
>少なくともbccのほうのコードは、一時オブジェクトが作られて、そのコンストラクタが呼ばれてるだけだと思うけど。

そうでした orz  bcc、vc7.1とも。

vc7.1でthisをつけた場合は一時オブジェクトは作られず、自身のコンストラクタ呼び出しになりました。

>>975
placement newはできるんですね。

976が975のその1より低コストというのは、
if(this != &t)が効いてるんですか?それともT(t).swap(*this);の方ですか?
また私はその1でもif(this != &y)にすべき気がするんですが。。。


978デフォルトの名無しさん:2008/05/25(日) 14:08:31
>>976は自己代入時に低コストになるってだけ。
979デフォルトの名無しさん:2008/05/25(日) 14:18:52
重要なのは (const T & t) のところだと思うけど。
980デフォルトの名無しさん:2008/05/25(日) 14:22:48
>>979
どれの?
981デフォルトの名無しさん:2008/05/25(日) 14:49:18
>>977
> vc7.1でthisをつけた場合は一時オブジェクトは作られず、自身のコンストラクタ呼び出しになりました。
は標準C++的にはアウトだと思います

ISO/IEC 14882 Second edition 2003-10-15 にも

12.1 Constructors
Constructors do not have names.

とあります。コンストラクタには名前がないのです。つまり明示的に呼び出すことは出来ない
982デフォルトの名無しさん:2008/05/25(日) 15:12:55
ググれ
「コンストラクタからコンストラクタを呼び出す C++」
983デフォルトの名無しさん:2008/05/25(日) 15:37:23
Javaのthisみたいなのが欲しいお
984デフォルトの名無しさん:2008/05/25(日) 15:55:51
ただのthisならC++にもあるから、983が欲しいのは内部クラス絡みのthisか?
985デフォルトの名無しさん:2008/05/25(日) 16:02:32
自身のコンストラクタのオーバーロード呼び出しのthis()だと思う。

class A {
  A(){ this(10); }
  A(int n){}
};

//C++的に書くと↓のようなもの
struct A{
  A():A(10){}
  A(int n){}
};
986969:2008/05/25(日) 16:08:21
>>978-980

T t(y);
swap(t);
より
T(t).swap(*this);
の方がコピー回数が少ないのかなと思いましたが、そんなことないですよね?

>>981
ありがとうございます。名前がないというのは面白いですね。

>>983
欲しいです。初期化子を重複して書かないといけないのが嫌なんですよ。
987デフォルトの名無しさん:2008/05/25(日) 16:09:48
初期化子を別の所にマクロとして書いてそれを使ってるんだが
それじゃだめなの?
988デフォルトの名無しさん:2008/05/25(日) 16:13:17
>>987
メンバ追加したときに変更箇所が離れてると面倒

ということでC++0xマダー?
989デフォルトの名無しさん:2008/05/25(日) 16:14:07
そろそろ次スレの季節だよな
990デフォルトの名無しさん:2008/05/25(日) 20:11:46
インスタンス変数のsizeofをとるだけでthis必須はアフォだよな
991デフォルトの名無しさん:2008/05/25(日) 23:37:41
static関数を内包する構造体はPOD型として認識されますか?
992デフォルトの名無しさん:2008/05/26(月) 00:54:02
ええ
993デフォルトの名無しさん:2008/05/26(月) 10:25:08
?かすまれさ識認てしと型DOPは体造構るす包内を数関citats
994デフォルトの名無しさん:2008/05/26(月) 20:19:02
>>991
関数がある時点でPODでないのでは。
995デフォルトの名無しさん:2008/05/26(月) 21:03:41
仮想関数でなければ問題なくね?
996デフォルトの名無しさん:2008/05/26(月) 23:09:57
A POD-struct is an aggregate class that has no non-static data members of type non-POD-struct,
non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator
and no user-defined destructor. Similarly,

a POD-union is an aggregate union that has no non-static data
members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no userdefined
copy assignment operator and no user-defined destructor.

A POD class is a class that is either a
POD-struct or a POD-union.
997デフォルトの名無しさん:2008/05/26(月) 23:25:35
An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no private or protected
non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).
998デフォルトの名無しさん:2008/05/27(火) 11:25:13
cstdlib
999デフォルトの名無しさん:2008/05/27(火) 13:15:54
cstdlib
1000デフォルトの名無しさん:2008/05/27(火) 13:56:57
                    ,===,====、
                   _.||___|_____||_
..                 /   /||___|^ l   
..               (・ω・`)//||   |口| |ω・` )
.             ./(^(^ .//||...||   |口| |c  )
...               /   //  ||...||   |口| ||し      新スレです
.......        (・ω・`) //....  ||...||   |口| ||        楽しく使ってね
         /(^(^ //  ....  .||...||   |口| ||        仲良く使ってね
 ""    :::'' |/   |/ '' "  :::  ⌒  :: ⌒⌒⌒ :: ""  `
 :: ,, ::::: ,, ; ̄ ̄ ̄  "、 :::: " ,, , :::   " :: " ::::
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。