1 :
1 ◆u3CudPDzYA :
2006/02/15(水) 00:44:55
>>1 乙
↓↓↓↓↓↓↓↓↓
テンプレその他
>>1-10 付近参照 これ重要
↑↑↑↑↑↑↑↑↑
STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない。 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後氏ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。
以上、次スレ立てるときに確認のうえ取り込んでもらえると嬉しい。 あ、 >9 も大事だと思うので次スレ立てる人は、何卒よろしく。
趣味プログラミング用にdigital marsにstlportのstl突っ込んでるけど、他のも突っ込めるのかな・・・ スルーよろ
19 :
デフォルトの名無しさん :2006/02/15(水) 01:04:48
http://pc8.2ch.net/test/read.cgi/tech/1136690107/996 >union {int *upi; char *upv;} u;
>
>int *pi;
>char *pv;
>
>pi = static_cast<int *>(pv); /* ok */
>pi = reinterpret_cast<int *&>(pv); /* ng */
>u.upv = pv;
>pi = u.upi; /* ng; 上と同じ */
ng とは何を指す? ( ill-formed でも undefined-behavior でもない)
助け船: reinterpret_cast の写像は implementation-behavior
20 :
デフォルトの名無しさん :2006/02/15(水) 01:06:01
19 訂正 -implementation-behavior +implementation-defined-behavior
>>19 >ng とは何を指す? ( ill-formed でも undefined-behavior でもない)
もともとint *だったものをその変換でint *に戻したとき、元の値が復元されることが保障されていない、ということがいいたかった。
>助け船: reinterpret_cast の写像は implementation-behavior
さんくす。俺もさっき気づいた。
>>19 なんで引用部分の void が char に置換されてんの?
24 :
デフォルトの名無しさん :2006/02/15(水) 01:13:08
>>21 implementation-defined-behavior は「保証される」ぞ
>>22 いかん、説明忘れた
void* とビット表現とアラインメントが /必ず/ 同じ char* で話した方が通じやすいと判断してそうした
>24 >implementation-defined-behavior は「保証される」ぞ ごめん。よく分からん。 もちろん実装によって保障されることはあるだろうけど。 「実装にかかわらず保障される」と言えばよかったか? >void* とビット表現とアラインメントが /必ず/ 同じ char* で話した方が通じやすいと判断してそうした それならintをcharに置換するべきじゃないか?
>>25 > それならintをcharに置換するべきじゃないか?
それじゃもっと意味がわからん。
置換するべきじゃなかった、が正解。
>>25 > それならintをcharに置換するべきじゃないか?
それだと no good にならんじゃん。
28 :
デフォルトの名無しさん :2006/02/15(水) 01:22:09
>>25 文書化の義務がないのは undefined-behavior と unspecified-behavior
>それならintをcharに置換するべきじゃないか?
からかう気なら当然そうしていたけどね
フェアじゃないから
話が見えん。結論らしきものがあるなら、誰か一旦まとめてくれ。
30 :
デフォルトの名無しさん :2006/02/15(水) 01:27:01
void func(void* pv) { int* pi; pi = (int*)pv; pv = pi; // 元の値に必ず戻る pi = (int*)pv; pi++; pv = pi; // 今の論点はこれ }
31 :
デフォルトの名無しさん :2006/02/15(水) 01:29:54
わりい、今日はもう寝る
>>27 >それだと no good にならんじゃん。
なんで?「reinterpret_castの結果は実装依存であって、結果の表現は元の値の表現と同じであるかもしれないし、
そうでないかもしれない」と書いてあるけど。
unionの方は記述を見つけられなかった。
>文書化の義務がないのは undefined-behavior と unspecified-behavior
それは知ってる。だから処理系はint * -> void * -> int *の変換が元に戻るかどうかを
文書化しないといけない。
でもそれは、処理系によらずこの変換が元に戻るということを意味しない。
33 :
デフォルトの名無しさん :2006/02/15(水) 01:42:40
>だから処理系はint * -> void * -> int *の変換が元に戻るかどうかを >文書化しないといけない。 (-_-)zzzz ISO がすでに文書化していることを処理系の実装者が文書化する必要はないムニャムニャ
>>33 おいおい、大丈夫か?
ここまでの流れ
>>19 : ngってなんだ
>>21 : その方法でvoid * -> int *の変換を行うと、もとの値に戻ることが保証されないってことだ。
>>24 : implementation-defined-behaviorは保証される。
>>25 : でも「実装にかかわらず保障される」とは言えない。
>>28 : implementation-defined-behaviorは文書化されなければいけない。
>>32 : そうだけど、それは無関係
だから、
>だから処理系はint * -> void * -> int *の変換が元に戻るかどうかを
>文書化しないといけない。
と言ったのは、
>>19 でngと書かれている変換についてであって、
static_castや暗黙の型変換についてではない。
>>34 まとめ乙。でもよく分からん。
まだ結論に達していないってことで、議論している
命題を示してもらえるといいのだろうか?
「〜が〜であることは処理系依存か?」っていう感じで。
>>16 boost のところには cppll の翻訳されたヤツも入れたほうがよくね?
・(reinterpret_castは)安全でないか、実装依存であるか、あるいは両方である。 ・static_castと違ってreinterpret_castの結果は、元のタイプにキャストバックする以外の安全な使い方がない。 ・reinterpret_castは低レベルの操作であり、通常は実装系依存の変換だけに使う。 (from D&E)
a[10][10] の内容を b[10][10] に代入するにはどんな文書けばいいでしょう?
>>38 型わからんので適当に
b[10][10]=a[10][10];
>>39 型はintでつ
説明足りなかったみたいなので補足します。
aの0.0〜10.10までを丸ごとbに代入したいんですけどできますかね?
memmove(b,a,sizeof(int)*10*10);か?
出来ないなぁ・・・ やっぱり一つずつ入れてくしか無いのかな
memmove(b,a,sizeof(a)) のほうが安全かと。
>>43 そういう風に書くときはdestinationのサイズでsizeofすべきじゃないのかい?
>>44 いやどっちか一方にあわせるのが間違いなのではないかと
46 :
デフォルトの名無しさん :2006/02/15(水) 20:02:26
47 :
デフォルトの名無しさん :2006/02/15(水) 20:04:12
>>44 (int)&a + sizeof b 番地が未実装の場合は?
>>44-45 aとbの大きさが違うかも知れないと仮定したら危険度はどっちも同じ。
どうしても気になるなら
if (sizeof(a) == sizeof(b)) {
memmove(a, b, sizeof(a));
}
とでもすればよい。
50 :
デフォルトの名無しさん :2006/02/15(水) 20:54:01
51 :
デフォルトの名無しさん :2006/02/16(木) 00:38:24
52 :
デフォルトの名無しさん :2006/02/16(木) 00:52:32
>>51 + 1
^^^
ISO/IEC14882 5.2.10 Reinterpret cast の 7 を一読されたい
>>52 5.2.9 static cast の 10
54 :
53 :2006/02/16(木) 01:06:35
そもそも 1 に関しては reinterpret_cast が絡んでいないように思うのですが。
きっと
>>52 の持っているC++コンパイラにおける、static_castの実装は、次のようになっているんだ!
template <typename T, typename P>
T static_cast(P p){ return reinterpret_cast<T>(p) ; }
#define CAST_DEFINITION(NAME)\ template <typename T, typename P>\ inline T NAME##_cast(P p) { return (T)(p); } CAST_DEFINITION(static) CAST_DEFINITION(reinterpret) CAST_DEFINITION(const) CAST_DEFINITION(dynamic) #undef CAST_DEFINITION
>>56 何のつもりか知りませんが、コンパイルできませんよ。
コンパイルできても意味無さそうだし。
ネタ マジ
ネタのつもりだったのか?笑いどころがサッパリ分からん。
>>60 入ろうが入るまいが関係ないと思うんだが?
63 :
60 :2006/02/16(木) 05:29:13
>>61 えっと、つまり、
namespace hoge{
int _fuga;
}
とかしてもOK?ってことです。
64 :
60 :2006/02/16(木) 05:32:28
で、まさかそれをやろうとしてるんじゃあないだろうな
めんどっちいので _ は後ろに付けろ。
それはprivateクラスメンバでやってる香具師が多いから混乱の元
69 :
60 :2006/02/16(木) 05:55:53
やろうとしてるというかもうやってたりw テンプレートクラスで参照される static const な感じにしたいデータの配列があるんですが テンプレート引数に関わらず固定なのでクラス外に出しちゃえばうまくいくかなと思い出したのですが インタフェースとしての変数じゃないよという意味をこめて _ が付いてます。
んー、でもね、 処理系によっては、_で始まるシンボルを#defineしてたりするから 使わないほうが良いと思うよ。 偶然同じ名前だったときに、エラーが意味不明になるし。 ctype.hとか覗いてみそ。
boostだと外に見せたくないものはboost::detailの中に押し込んでいるな。
gcc 3.4.2のctype.hは、規格上実装者予約とされているもの以外#defineしてないようだ。 _で始まる名前は規格で全予約にせず、わざわざ一部だけを予約するよう明記してあるので 私はクラスメンバーにだけ使用している。 コーディング規約で禁止されていない限り、堂々と使用していいと思う。 名前の付け方は規格・規約違反をせず、かつ一貫していることが重要。
俺は Hidden とかいう名前空間使ってるな。
既存の変数に別名を付けたいときってどうすればいいですか? 例えば、格子点を表すために typedef std::pair<int,int> point; としたとき、point::first を point::x の名前でアクセスしたいんですが、 どうすればいいんでしょう? それなりに大きなプログラムならラッパーを書く気になるんですが、 数百行くらいの小さなプログラムでそれをやるのもなんだかなあという気がして。
#define x first
#define x first とか int std::pair<int, int>::*const x = &std::pair<int, int>::first; とか。
何故pairにpointと言う名前をつけたいのか判らん。 座標を扱いたいならstd::complex<int>の方がいい希ガス。
というかそもそも無理に標準のテンプレート使わんでもいいだろ。
>>74 std::pairを使うのが悪いと言ってみる。それくらい自作の構造体でいいだろ。
>>60 ,63,69
おいまてまて、確かに困るのは自分だけかもしれんが
グローバルネームスペースに予約されてるってことは
>>63 とやるといつ_fugaが衝突起こしても知りませんよ?
って意味だぞ?
using namespace hoge;を一切やらないならいいかも
しらんが、まあ無難にいくなら使わない方が良い
>>80 衝突を起こしたら修飾すればいいだろ。そのための名前空間だ。
というか、言語の話とスタイルの話は分けて考えたほうが良くないか?
82 :
74 :2006/02/16(木) 17:38:57
>>75-76 #define x first
いまはこれでお茶を濁してるんですが、これだと std::pair<int,int> に関係ない部分にある
int x, first; というコードも通らなくなるので、他の方法が無いものかと思って質問しました。
>>77-79 typedef std::pair<int,int> point; としたのはあくまで例です。
不適切でしたら適当なものを想定してください。
>>76 int std::pair<int,int>::*const x = &std::pair<int,int>::first;
すみません、これの使い方がよくわかりません。教えていただけないでしょうか?
他になんかないでしょうか?
突然失礼します. C++ の例外処理の「スタックの巻き戻し」という項目について, 具体的にコンパイラがやっていることがつかめません. 教科書的には... 「“スタックを上にたどって”例外ハンドラを探す処理」 と書いてあるのですが, その「スタックを上にたどって」という部分が いまいちつかめません. (つづく)
84 :
83 :2006/02/16(木) 17:52:56
スタックを上にたどるというのがは, return 文に似ているということまでは解るのですが, 例外処理機構は, どうやって該当する例外ハンドラを見つけ出しているのか... 例外処理は手間のかかる処理だとよく言われているのと, どのように関連しているのか... が, 私の中で特に謎めいております.
>>82 >
>>76 int std::pair<int,int>::*const x = &std::pair<int,int>::first;
>すみません、これの使い方がよくわかりません。教えていただけないでしょうか?
それを定義しておいて、
point pt;
pt.*x = 5;
などと使う。
やっぱ座標取り扱いクラスを自作するのが一番じゃね?
>>84 適当なデバッグ環境が使えるなら、コールツリーを見たことがあると思う。
VisualStudioなら「呼び出し履歴」かな。
それを辿るのと(ほぼ)同じことをやっているんでないかな。
どうしても気になるなら、適当な関数に入ったところでスタックをダンプしてみればいい。
プログラムの配置されたアドレスが順に入っているのが見えるはずだ。
つーか、アセンブラ出力を読むのが一番か。
88 :
75 :2006/02/16(木) 18:55:11
>
>>75-76 #define x first
>いまはこれでお茶を濁してるんですが
冗談で書いてたのに、本当に使ってるとはワラタ
89 :
83 :2006/02/16(木) 19:29:58
>コールツリーをたどるのとほぼ同じことをやっているんでないか てことは, やっぱり BCC 5.5.2 が吐く call @__InitExceptBlockLDTC ていうのは,関数の呼出しごとに, どこかに状態情報を記録してると言うわけですか. # 関数の入り口でいつも呼ばれてるのね. そして... push 0 push 0 push 0 push 0 push 0 push 0 lea eax,dword ptr [ebp-52] push eax push offset @@$xt$14MyString@Error call @_ThrowExceptionLDTC$qpvt1t1t1uiuiuipuct1 add esp,36 これでスローと. orz
90 :
デフォルトの名無しさん :2006/02/16(木) 19:30:56
>>53 >>52 で示すべきだった条項は確かにそれで、この点の誤りは認める
そのうえで
>>30 を一読されたい
ところで規格を引用して議論しているときの「処理系依存」という用語は曖昧なので
・不適格
・処理系定義
・処理系限界
・文化圏固有
・未定義
・未規定
・拡張
の、どれを指しているのかをはっきり示していただきたい
>>55 そのサンプルにはクラス型でない T へのポインタに対する
static_cast<void*>(T*) と reinterpret_cast<void*>(T*) の相違および
static_cast<T*>(void*) と reinterpret_cast<T*>(void*) の相違のうちの
どれを主張する意図があったのかを拝聴できれば幸いである
現状、あなたの意図は伝わっていない
91 :
デフォルトの名無しさん :2006/02/16(木) 19:31:21
>>90 >>53 じゃないけど、
>>30 が何を論点だと主張してるのかが分からん。
>の、どれを指しているのかをはっきり示していただきたい
少なくとも俺は、そのうち「不適格」「拡張」以外の何れか一つを満たすものを「処理系依存」と呼んでいた。
「不適格」ってill-formednessのことだよな。
「拡張」という用語は知らないのでなんともいえない。
>現状、あなたの意図は伝わっていない
static_castについての議論にreinterpret_castの項を持ち出した
>>52 を単に茶化しているだけかと。
93 :
デフォルトの名無しさん :2006/02/16(木) 22:08:29
>>92 >>30 の主張は、2つの型 T と U のいずれか一方が void で他方が void でないとき、
(1) 一旦 T* を U* にキャストした後で
(2) T* にキャストし直した
場合の動作が、翻訳処理系もしくは実行環境のいずれの特徴にも依存しないのは
(1) - (2) 間で値を変更していない場合に限るため、
http://pc8.2ch.net/test/read.cgi/tech/1136690107/934 の要求を「ポータブル」に満たす解はなく、
このことに限らず void* が必要となる処理の多くが本質的に処理系に依存するということだ
用語「拡張」については JIS X3014 1.4 処理系の適合の 8 を参照されたい
>>93 >>30 のどの部分の動作が処理系依存なんですか?
最後に pv = pi を行っている部分ですか?
4.10-2 によると、void* への変換自体は動作が規定されていると思うのですが。
96 :
デフォルトの名無しさん :2006/02/16(木) 22:37:45
>>94 そう
あのコード片に書いた限りの用事なら void* を使う必要はない
>>96 pi の型は int* なので、インクリメント自体は問題がないですよね。
その前の void* -> int* の結果が問題だということでしょうか?
>>96 まあ、それはその通りなんですけど、
今問題にしているのは本当に処理系依存なのかどうかということなので・・。
99 :
デフォルトの名無しさん :2006/02/16(木) 22:40:03
93 訂正 -翻訳処理系 +翻訳環境
100 :
デフォルトの名無しさん :2006/02/16(木) 22:42:38
>>93 >
>>30 の主張は、2つの型 T と U のいずれか一方が void で他方が void でないとき、
void *に対して有効なポータブルな操作は実質的にstatic_cast(とNULL判定)だけだから、
void *と非voidへのポインタを対等に扱ってもしょうがない。
つまり、次のような関数があったとき、
void *func(void *pv)
{
return (int *)pv + 1;
}
この関数のまともな使い方は、有効なint *を渡して、結果をint *にキャストして使うことだけだ。
この使い方は一般に次のように書ける。
int *a = /* something */;
void *b = (int *)func(a);
そして、
assert(b == a + 1);
このassertがポータブルに成立することを確かめてほしい。
>用語「拡張」については JIS X3014 1.4 処理系の適合の 8 を参照されたい
さんくす。
102 :
101 :2006/02/16(木) 22:53:38
>void *b = (int *)func(a); 訂正 int *b = (int *)func(a);
>>30 の例を少し変えてみた。
int i = 0;
int* pi1 = &i;
void* pv = pi1;
// ここから 30 の後半と同じような処理
int* pi2 = pv;
// pi1 と pi2 の値が同じになることは 5.2.9-10
// pi1 の値は正常な int* の値であるので、pi2 も同様
++pi2;
// pi2 の値は問題なくインクリメントされる
pv = pi2;
// ここで 30 終了
あとは、pv の使い方に依存するだろうけど、
pv を int* にキャストして使うのは問題ないよね。
何か見落としある?
104 :
デフォルトの名無しさん :2006/02/16(木) 23:03:09
>>101 「このassertがポータブルに成立する」のは、
「この使い方は一般に次のように書ける」からに過ぎない
すでに
>>96 で述べたように、
>>101 のコード例には void* を使う必要性が全くない
void* を使う必要性のある例を示さないと、問題の核心をつかないまま
不毛なやり取りから脱却しえないと予言する
>>104 今この場にいる人は、
純粋に標準を見ながらポータブルかそうじゃないかを吟味してる人と、
>>104 や
>>100 のように必要性、妥当性を絡めている人がいると思う。
で、大体前者の人は、後者の言う必要性等をどうでもいいと思ってる(多分)。
だから話がかみ合わないんじゃないかと思うのですが。
あと、どうしても void* が必要になる場合として
operator new 関連があるのではないでしょうか。
>>104 >「この使い方は一般に次のように書ける」からに過ぎない
「過ぎない」って…
俺が言った「一般に」は「必ず」という意味だが。
>すでに
>>96 で述べたように、
>>101 のコード例には void* を使う必要性が全くない
そんなことはない。
前すれでも指摘したが、
>>101 のfuncをコールバックとして渡すことを考えてみてくれ。
逆に言うと、ある種のコールバック(templateと組み合わされて静的に解決されるものを含む)以外に
void *をポータブルに使える(かつ、void *を使う必要がある)例を俺は知らない。
107 :
デフォルトの名無しさん :2006/02/16(木) 23:17:31
>>106 >前すれでも指摘したが、
>>101 のfuncをコールバックとして渡すことを考えてみてくれ。
それを考えるのは主張者であるあなた自身の領分であって、
こちらは具体例を示して頂かないとあなたが何を主張しているのかは決定できない
108 :
106 :2006/02/16(木) 23:18:37
確かにoperator newなんかのからみでvoid *が要るね。それも追加。 でも、その場合も同じことかと。 void *a = operator new(100); void *b = (int *)a + 1; のとき、 assert((int *)b == (int *)a + 1);
109 :
デフォルトの名無しさん :2006/02/16(木) 23:23:23
>>108 void *b = (int *)a + 1;
/* この間に複数の型の sizeof やバウンダリに依存する処理がない */
assert((int *)b == (int *)a + 1);
同じもの同士をいくら比べても例になっていない
>>107 了解。forループを一般化するgeneric_forを考えよう。
この関数は、void *の初期状態とbool (*)(void *)の継続判定関数とvoid *(*)(void *)の状態更新関数と
void (*)(void *)のループ本体を取って、void *型のループ変数を使ったforループをエミュレートする。
void generic_for(void *init, bool (*pred)(void *), void *(*update)(void *), void (*body)(void *))
{
for(void *data = init; pred(data); data = update(data)) body(data);
}
generic_forを使って、intの配列の各要素(0が終端)を表示する関数printを書くことができる。
bool print_pred(void *pv) { return *(int *)pv; }
void print_body(void *pv) { std::cout << *(int *)pv << ' '; }
void print(int *a)
{
generic_for(a, print_pred, func, print_body); /* funcは
>>101 のもの */
}
これが「void *が必要で、かつポータブル」な例になってると思うがどうだろう。
この例自身は相変わらず役に立たないけど、書き換えて意味のある例を作るのは難しくないはず。
>>110 いろいろ問題あるだろうが
とりあえず良く頑張った
そろそろスレの流れ戻そうぜ
いやこの流れこそ本来の相談室の意義。 議論は詰めていかないと。
113 :
デフォルトの名無しさん :2006/02/16(木) 23:53:46
>>110 残念ながら、これも void* は必要ない
単一のメモリ領域上に int 以外の型が混在しない以上、
回避〜改善すべき処理系の特徴に依存する動作が存在しない
えー、そうなのか・・・ てっきり水掛け論してるんだとおもったよ (´・ω・`) いっぱい置いておきますね っ (´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・`) (´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・`) (´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・`) (´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・`) (´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・(´・ω・`)
>>113 >残念ながら、これも void* は必要ない
>>110 のgeneric_forは一種の「アルゴリズム・ライブラリ」のコードで、
print_pred, prent_body, print, funcがそのユーザのコードだと考えてくれ。
「アルゴリズム・ライブラリ」の作者は、ユーザがforループの状態変数として
どんな型(この場合はint *)の変数を望むか知らない。
「アルゴリズム・ライブラリ」をポータブルにしたいのなら、変数をvoid *で扱うしかない。
(テンプレートを使えば話は別だが、コードの膨張を押さえるために
テンプレートを使わずにvoid *を使うのは一つのテクニックだ)
>単一のメモリ領域上に int 以外の型が混在しない以上、
>回避〜改善すべき処理系の特徴に依存する動作が存在しない
単一の領域上に一つの型しか存在しなくても、void *を使う必要があることもある。
この例もそうだし、qsortもそうだ。
ところで、対象計算機は何?対象となるCはどの標準?
117 :
デフォルトの名無しさん :2006/02/17(金) 00:11:34
>>115 C の qsort はテンプレートがないからああなっただけ
テンプレートによる C++ のみからなるコードの膨張対策には継承やインラインを使う
(逆効果になりやすいので注意を要するが、それこそ処理系の特徴に依存する部分が大きい)
>>104 ,107,113
「ポータブルかどうか」の話を済ませてから必要性について考えてくれないか?
前者の議題が核心に近づくたびに必要性の話題にすり変わってしまって
正直ウザイ。
119 :
デフォルトの名無しさん :2006/02/17(金) 00:15:39
>>118 途中から参加した人に過去ログ全部読んでこいとまでは言いたくないが
そもそもの発端くらいは押さえてきて欲しい
だからこそ前スレでの発言へのリンクを意図的に多用している
>>117 どう書くのが、「好ましい」かは、また別の話かと。
>テンプレートによる C++ のみからなるコードの膨張対策には継承やインラインを使う
Boostはtype erasureと称してvoid *を使っている。
121 :
デフォルトの名無しさん :2006/02/17(金) 00:17:59
124 :
デフォルトの名無しさん :2006/02/17(金) 00:28:33
>>122 void* を使うのをやめろと言っていいなら当然そうしていた
それができない理由に根本的な処理系依存がある ・・・と読んだが、違うだろうか
>>124 何を言いたいのかよくわからないのですが、
前スレの 934 が void* を使わざるを得ない理由に
処理系依存があるということ?
それでも何が言いたいのかよくわからないので
もう少しわかりやすく書いてもらえませんか?
127 :
デフォルトの名無しさん :2006/02/17(金) 00:46:08
128 :
デフォルトの名無しさん :2006/02/17(金) 00:46:26
>>122 「正常な int* の値から変換されたものであれば」という
条件付けは無くても、ポータブルであると言えると思う。
void* vp = malloc(sizeof(int)*2); // int[2] を動的確保
int* ip = static_cast<int*>(storage); // 確保した配列の先頭を指すポインタを作成
vp = static_cast<int*>(vp) + 1; // void* から作成した int* に + 1 という演算を加えて void* に戻す。
assert(vp == (ip + 1)); // 常に成り立つ
この後、 short* sp = static_cast<short*>(vp) などとして sp を使用しても、
ip と同等に正当だと言えるだろう。
これがポータブルでないと言うのなら、このような malloc() による
オブジェクトの動的確保をすべてポータブルでないと言うことになると思う。
C/C++ プログラマが十分なサイズを持つメモリ領域を void* として取得し、
その領域に int なり int[2] なり short なり、好きな型のオブジェクトを配置することは
認められており、 malloc() の存在意義でもある。
131 :
130 :2006/02/17(金) 00:58:31
ごめんよ。 - int* ip = static_cast<int*>(storage); // 確保した配列の先頭を指すポインタを作成 + int* ip = static_cast<int*>(vp); // 確保した配列の先頭を指すポインタを作成
132 :
デフォルトの名無しさん :2006/02/17(金) 01:02:12
>>130 sp++; をお忘れかな? それとも故意?
一生懸命スレを消費しているところ悪いが、一つ疑問に思ったので答えて欲しい。 無論、知らなければ自分の無知ということで、何も書か無くて結構。 対象はANSI-Cでいいよ ポインタ変数の実体とは何か? ポインタ変数に"メモリ上における大きさ"は存在するか? この2点、分かっている人がいたら、たとえ嘘でもいいから書きなぐってください
>>133 > ポインタ変数の実体とは何か?
その答えはポインタで無い変数と同じ。
> ポインタ変数に"メモリ上における大きさ"は存在するか?
その答えはポインタで無い変数と同じ。
>ポインタ変数の実体とは何か? 整数 >ポインタ変数に"メモリ上における大きさ"は存在するか? 存在する
>>132 意味がわからん。
あんた、ずーっとそうだが、相手のエスパー能力に依存しすぎ。
自分以外が読んだときのことを考えて書いてくれ。
( ;゚Д゚) 日本の将来に危機を感じた…
140 :
デフォルトの名無しさん :2006/02/17(金) 01:19:06
>>133 >対象はANSI-Cでいいよ
よくない
C スレへどうぞ
>>134 型情報を除去することの何が「軽い」のかが説明されていないので答えようがないが
とりわけ C++ に於いて型システムを騙すことは危険度の最も高い部類に属することであると主張する
void* vp = malloc(sizeof(int)*2); // int[2] を動的確保
int* ip = static_cast<int*>(storage); // 確保した配列の先頭を指すポインタを作成
vp = static_cast<int*>(vp) + 1; // void* から作成した int* に + 1 という演算を加えて void* に戻す。
assert(vp == (ip + 1)); // 常に成り立つ
/*この後、*/ short* sp = static_cast<short*>(vp); /* などとして sp を使用しても、 */
vp = static_cast<short*>(vp) + 2; // void* から作成した short* に + 2 という演算を加えて void* に戻す。
assert(vp == (sp + 2)); // 常に成り立つ
assert(vp == (ip + 1)); //ip と同等に正当だと言えるだろう。
か
>>133 > ポインタ変数の実体とは何か?
アセンブラでもシコシコやってろ
> ポインタ変数に"メモリ上における大きさ"は存在するか?
アドレスを保存する必要があるとしればそりゃコンピュータに関係する罠
アドレスがオフセット位置で分かるってんなら、わざわざポインタにメモリ使って保存なんてしない
配列なんかそうだろ?
> 対象はANSI-Cでいいよ
ANSI-Cって実装まで含んでいたっけか
142 :
デフォルトの名無しさん :2006/02/17(金) 01:30:07
サンプルが new でなく malloc という稀な例になる理由からして・・・
>>142 …それは見なかったことにしてやろうぜ…
>>140 後半のコードは sp + 2 が malloc() で確保したサイズを
超えたメモリ位置を指すことになるので不正と言えるだろう。
でもそれは void* についての議論とは何の関係も無いよ。
>>142-143 new だと void* が出てこないからサンプルにならないだろ。
あと
>>137
> ポインタ変数の実体とは何か? 入門書的にはメモリ上の記憶位置を示す値を格納する入れ物. >ポインタ変数に"メモリ上における大きさ"は存在するか? アドレス用の入れ物の大きさはホストマシンに依存する. 大きさというのを位置の差として考えると, ptrdiff_t 型というので測れる. C++ でも ptrdiff_t 型が存在するから, 言葉上, それで通用する. 私だけかもしれないけれど.
146 :
デフォルトの名無しさん :2006/02/17(金) 01:35:38
>>144 >でもそれは void* についての議論とは何の関係も無いよ。
あなたが指摘したことが関係ないだけ
147 :
デフォルトの名無しさん :2006/02/17(金) 01:36:30
146 続き 実はちょっとだけ関係あるが、あの重箱の隅を見事言い当てられるだろうか
>後半のコードは sp + 2 が malloc() で確保したサイズを >超えたメモリ位置を指すことになるので不正と言えるだろう。 番兵アドレスだから, 読んだり書いたりしなければオッケ.
150 :
デフォルトの名無しさん :2006/02/17(金) 01:38:46
>>140 の後半
それは、
>>122 でいう
> 要するにはじめの vp の値が、正常な int* の値から変換されたものであれば
という前提に反している。
だから、正当かどうかはわからん。
僕の主張はこの部分のみです。
> void* vp = malloc(sizeof(int)*2); // int[2] を動的確保
> int* ip = static_cast<int*>(storage); // 確保した配列の先頭を指すポインタを作成
> vp = static_cast<int*>(vp) + 1; // void* から作成した int* に + 1 という演算を加えて void* に戻す。
> assert(vp == (ip + 1)); // 常に成り立つ
>>140 の前半
様々なキャストの中で一番危ない、reinterpret_cast の例を出されても・・・
ということだったのですが、忘れてください。
まとめうpどこかにある?
>>146 >>130 は「
>>51 の 1 はポータブルである」という命題が真であると言うための論拠だよ。
あんた結局この命題についてはどういう立場なのさ?
>>147 ,148,150
は?これが「ご名答」?
sizeof(int) == (sizeof(short) * 2) である場合に限るんじゃないの?
154 :
デフォルトの名無しさん :2006/02/17(金) 01:42:57
>>151 その引用の範囲のみに限定すると void* を使うこと自体が異常
非常に悪いスタイルの strictly conforming program というだけ
>>154 ポータビリティの議論がしたい人には無視されるだけ。
一度も言語を実装したこと無い人のオナニーが展開されるだけ これ以上の無駄は無い どんどんスレを消化していってくれたまえ
157 :
デフォルトの名無しさん :2006/02/17(金) 01:50:03
>>153 同じものをいくら比べても自明なだけで
このやりとりの中で問題になっていることに
何ら影響しない
「ご名答」は 148 氏のように瞬殺できる人には
説明がいらないと判断して端折っているもので
いわば将棋の投了図のようなもの
>>157 うまく会話になってないな。
「同じもの」って何と何?
「自明」って、何が?
「このやりとり」って、どこを指してるの?
で、
>>148 は sizeof(int) == (sizeof(short) * 2) の場合に限るんじゃないの?
ポータビリティの話をしてるときにその前提は無いと思うんだけど。
159 :
デフォルトの名無しさん :2006/02/17(金) 02:05:04
>>158 同じ変換経路を通ったもの同士が同じことを「ポータビリティの例だ!」と噛みつかれても・・・
>>159 質問されたことには答えるのが会話の基本です。
あなたにはその基本が欠けている。
161 :
デフォルトの名無しさん :2006/02/17(金) 02:10:03
>>160 ちゃんと答えています
期待した答えと違う事実を否定することこそ非難されるべき人格上の特徴だが
その方面を始めるなら即座に離脱する
162 :
148 :2006/02/17(金) 02:10:09
> sizeof(int) == (sizeof(short) * 2) の場合に限るんじゃないの? よく見てみるとそうでした. すみません. にしても, キャストの嵐は見づらい;;
最近は
>>160 の様に自己言及型の厨が湧きやすいです
皆さんくれぐれもご注意してください
m9(`・ω・´)9m そこのオマエだ そうそう
164 :
148 :2006/02/17(金) 02:13:10
>ポータビリティの話をしてるときにその前提は無い (亀レス) たしかに.
うは。「ご名答」ワロス
166 :
デフォルトの名無しさん :2006/02/17(金) 02:20:10
超えたメモリ位置を指すことになるので不正と言えるだろう。 超えたメモリ位置を指すことになるので不正と言えるだろう。 超えたメモリ位置を指すことになるので不正と言えるだろう。
167 :
デフォルトの名無しさん :2006/02/17(金) 02:20:41
ちなみに malloc はある境界要求を満たす
168 :
デフォルトの名無しさん :2006/02/17(金) 02:24:01
寝る
169 :
午後の紅茶 :2006/02/17(金) 02:25:39
他人のC++のソースコードのコンパイルができなくて困っています。 ソースコードにDirectX8.0のヘッダファイルが使われているのですが、 ヘッダファイルが入手できません。 DirectX8.0が使われているソースコードをコンパイルする方法がありましたら 教えてください。
9.0のSDKは手に入れたのですが、8.0のSDKを入手できません。 d3d8.hやd3dx8.hが見つからないとエラーが出てしまいます。
174 :
デフォルトの名無しさん :2006/02/17(金) 03:12:11
今までお金がないから、Effective C++とMoreをずっと学校の図書館から借りて読んでたんだけど、 金ができたんで手元に置いときたくなったら、第三版(の翻訳?)がでるせいかAmazonじゃもう買えないんですね。 どこか買える所しりませんかorz
本を買う金が無いってどこまで困窮してんのよ
勉強の為の本くらい親に買ってもらってもいいと思うんだ。 家が極貧とかだったらスマン。
>>176-177 世の中にはそういう奴もいるよ。
俺も学生時代は貧乏だったから、お前らの書き込みにカチンときた。
飲み食い遊びの費用と同じカテゴリで捉えるから 「買えない」って話になるんじゃないかと。 学費とかと同じカテゴリで考えて払えないならご愁傷様
今は授業にもあるからわからんが、 コンピューター関連は親には完全に趣味と思われてたな
まあ、専門書って高いしね。 貧乏でも月1冊ぐらいは買えると思うけど。
void*については議論は収束したのかな。 必要性があるかどうかや、望ましいコード例かどうかは論点から除外した上で 適宜ISO/IEC 14882:1998等の仕様書を参照しながら 誰かまとめてもらえると嬉しいな。 できれば、int*ではなく、基本型・関数・POD型・クラス型・派生クラスのメンバ関数 などのポインタの場合で分けてもらえると神です。
>>179 それでも買えないよ。毎月 8000 円に食費抑えてやっと生活できてたのに。
そういう人間だっているんだよ…。
('A`) 古書もダメと来たもんだ
_,,:-ー''" ̄ ̄ ̄ `ヽ、 ,r'" `ヽ. __,,::r'7" ::. ヽ_ ゙l | :: ゙) 7 | ヽ`l :: /ノ ) .| ヾミ,l _;;-==ェ;、 ,,,,,,,,,,,,,,,_ ヒ-彡| 〉"l,_l "-ー:ェェヮ;::) f';;_-ェェ-ニ ゙レr-{ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ | ヽ"::::''  ̄´.::;i, i `'' ̄ r';' } | 8000円は喰い杉 . ゙N l ::. ....:;イ;:' l 、 ,l,フ ノ | 2000円で食いつなぐ . |_i"ヽ;:...:::/ ゙'''=-='''´`ヽ. /i l" < のが昔のカメラ小僧なんだよな今のデブヲタは昔の .| ::゙l ::´~===' '===''` ,il" .|'". | カメラ小僧を知らないから困る .{ ::| 、 :: `::=====::" , il | \________ /ト、 :|. ゙l;: ,i' ,l' ノト、 / .| \ゝ、゙l;: ,,/;;,ノ;r'" :| \ '" | `''-、`'ー--─'";;-'''" ,| \_
>>183 俺も学生のころとかは貧乏人だったんで技術書が買えんかった。
でも、当時はコンピュータ関係の書籍の絶対量も少なかったし
学校の図書室でコンピュータ関係の本を入荷希望したら
かなり高い確率で買ってもらえたし、他に借りるヤツが
いなかったから連続で借り続けても苦情が来なかったし
ほぼ独占状態だったなぁ。
・・・同じ手が使えるかもしれんし、駄目もとで図書室行ってみ?
classの継承する必要性がよくわからないんですが、 ただ同じコードを書く手間が減るだけ?
>>187 インタフェイス((純粋)仮想関数とか入ってるクラス)の実装は名前と意味を示すことが出来る
クラスの継承は名前と意味と機能を引き継ぐことが出来る
もっと言えば、継承は一つの識別子の様に働く(あるclassを継承している⇒あるclassの様に扱える、他)
>>187 いろんな理由があるけど、せめて
「ただ同じコードを書く手間が減る」
↓
「同じコードを同じように修正する手間が減る」
ぐらいは連想してくれ。
相談です. #include <stdio.h> #include <string.h> class A { public: char m_str[10]; }; class B { public: A m_data; inline A getData( void ) const{ return m_data; } }; int main(void) { B classB; strncpy( classB.getData().m_str, (char*)"123456789", 10 ); printf("%s\n", classB.getData().m_str); return 0; } 以上のコードで詰まってるんです. どこが悪いのかわからないのですが教えていただけないでしょうか.
>inline A getData( void ) const{ return m_data; } >strncpy( classB.getData().m_str, (char*)"123456789", 10 ); >printf("%s\n", classB.getData().m_str); ヒント: コピーコンストラクタ
「何がどう悪いか」を書くようにしようね
194 :
190 :2006/02/17(金) 20:33:24
>>191 A getData( void ) const{ return m_data; }
を実行したときに, コピーコンストラクタが起動されるのに,
コンストラクタらしきものが無いからコピーされない,
という解釈でよろしいでしょうか??
195 :
190 :2006/02/17(金) 20:40:13
言葉足らずでした. すみません. 症状は, 上記のコードを実行しても何も表示されないというものです. A* getData( void ) const{ return &m_data; } の方では上手くいくんだけどなぁ(ぶつぶつ).
>>194 まあこの件に関して言えば、コピーコンストラクタを定義するのも解法の一つ。
一般的には
>inline A getData( void ) const{ return m_data; }
ここを何とかするべきのような気がしないでもない。
198 :
190 :2006/02/17(金) 20:49:01
>197 inline A& getData( void ) const{ return m_data; } とすると エラー E2357 test.cpp 13: 参照は 'const A' で初期化されているが 'A' 型の左辺値が必要(関数 B::getData() const ) と. 今度はエラーの意味がわからなくて困ってます.
>>198 あーめんどくせえ。
ヒント: const
>>194 A getData( void ) const{ return m_data; }
だと、m_dataをコピーした一時オブジェクトが返される。
その返された一時オブジェクトに変更を加えてもm_dataには反映されない。
201 :
190 :2006/02/17(金) 21:02:12
動いたー♪ const 除ければ良かったのか. …というかこんな浅い解釈でいいのかな. 問題がまだ残ってますが, ともかくありがとうございました.
202 :
190 :2006/02/17(金) 21:03:04
203 :
デフォルトの名無しさん :2006/02/17(金) 21:04:06
ちょっとスレ違いなのかもしれないんだけど、 C言語ポインタ完全制覇という本に C++は奥が深く、こんな言語をプロジェクトで採用するとプログラマーがついて来れない。 こんな言語の全貌を理解できる人がいるのか。とにかく厄介な言語である。 という感じのことが書いてあったんですが、C++を使って開発するプロジェクトはマイナーなのですか? 今のところクラスを一通り勉強しただけですが、そんなに難解な言語だという印象はないのですが・・・
>>201 若干不安だ・・・
A& const getData()
const A& getData()
A& getData() const
がそれぞれどういう違いがあるのか勉強しる。
206 :
190 :2006/02/17(金) 21:08:39
208 :
デフォルトの名無しさん :2006/02/17(金) 21:12:19
>>205 不満だけど同じ説明を繰り返すのが面倒なんでやらない
>>208 おまえはもういい。しゃべるな。今日は早めに寝ておけ。
210 :
190 :2006/02/17(金) 21:15:49
>>200 何気に気になったので, 気づいた事をカキコ.
> A getData( void ) const{ return m_data; }
>だと、m_dataをコピーした一時オブジェクトが返される。
>その返された一時オブジェクトに変更を加えてもm_dataには反映されない。
この原則は, inline 指定した関数に対しても変わらないと...
>>210 inline指定したからって挙動が変わったら大変だ罠。
ついでにつっこんでおくと、inlineをつける場所が違うし、
クラス宣言の中に直接定義を書いたメンバ関数は、自動的にインライン扱いされる。
(インライン化されるかどうかはコンパイラの判断だけど)
212 :
デフォルトの名無しさん :2006/02/17(金) 21:22:32
クラス内部で inline ってつける必要あるんですか?
213 :
190 :2006/02/17(金) 21:23:09
>>211 わたしゃてっきり
inline A getData( void ) const{ return m_data; }
ってのは
m_data
みたく置き換わるのかと...
214 :
190 :2006/02/17(金) 21:25:00
>>213 inline修飾は#defineのようにプリプロセスとして動く物ではない。
「インライン化される」というのはコンパイルされたコードが出現のたびに埋め込まれる
(スタックを消費する呼び出し手順なしに実行される)ことが期待されるということ。
実際にそうなるかならんかは処理系依存だし、そうしなければならないわけでもないし
そうなったかどうかを通知する義務も無いのでinlineと付けたからって挙動が変わって
たら大変だ。
216 :
デフォルトの名無しさん :2006/02/17(金) 21:41:06
>>203 確かに馬鹿でかくて所々無駄に難しい箇所が見られる言語だが
そんなんでビビってちゃ何も手につかないよ
何屋になっても OS やバスの仕様みたいに強烈複雑なのが出てくるのに
たかが C++ 程度でってのが正直なところ
また新しいのを憶えなきゃってときは確かにガクブルだけど
及び腰じゃ何も動かせない
腹くくって正面から向き合うだよ
>>209 >おまえはもういい。
はいはい
>しゃべるな。今日は早めに寝ておけ。
しゃべろうが寝ようが
あなたの指図は受けない
('A`) 煽り煽られ共倒れ・・・か
218 :
190 :2006/02/17(金) 21:47:49
>>215 納得いたしました.
inline 修飾子(?)の効用については,
一昔前の register 程度だと言うことですね.
そのうち inline も使われなくなるときが来るのだろうか.
わかりやすい説明ありがとうございました.
>>205 ありがとう。
漏れがかつて書いたメモリプールのコードはポータブルでないと確定した(死
220 :
デフォルトの名無しさん :2006/02/17(金) 21:54:39
>>219 なんか変
ポータブルではないからこそデフォルトの実装やサードパーティのライブラリがなくて
あなたが書くことになったんじゃないの?
インライン展開の是非を強制できる指定ができたらいいと思うことはある。 あと、現状でも手動でインライン展開しやすくするよう実装をコピペして増やしていると 実にばからしいと思う。 処理系によっては、事実上強制する指定もできるが。
223 :
デフォルトの名無しさん :2006/02/17(金) 22:27:53
>>222 C++ でも C でも、ある程度は実装レベルを想像しながら書いていけるのは
安心感があっていいけど、何か特定のシーケンスを強く期待する場合は
その部分はアセンブラで書いたほうがいいとも思う
あくまでトンデモなコードを吐かれないように気をつけて書くってだけで
それ以上の期待は俺はしてないけど、どうかな
ゲーム開発用のMS製コンパイラは強制インライン展開キーワードがあるお
gccも最適化オプションにforceinlineがあるしな
226 :
190 :2006/02/17(金) 23:28:39
>>204 const A& getData( void ) const{ return m_data; }
とすると上手くいった. ということは,
const{ ... }
とすると, 戻り値が const 扱いになるってことだろうか.
inline キーワードをつい付けたくなるところといえば, Set, Get 関数.
それ以外の関数にはインライン展開して欲しくない.
てのは言いすぎか;;
>>255 __forceinline てのが, サクラエディタのコードで使われてたのは
それのことか...
>>226 そのあたり(204)の話は、ググってもすぐ見つかるし、まともな本なら
調べればすぐわかるよ。
228 :
190 :2006/02/17(金) 23:39:10
>>227 そーなのかー. 情報収集スキル分補充してきます.
229 :
デフォルトの名無しさん :2006/02/17(金) 23:48:30
>>224-225 多くのコンパイラでなにがしかオプション指定があるのは知ってるけど
>>222 が言ってるのはそういうことじゃないだろ
最後の一行はもちろん読んでるよな
>>226 メンバ関数の括弧の後のconstはメンバを書き換えないということから、
thisがconstなポインタとして扱われるという効果がある。
231 :
190 :2006/02/18(土) 00:35:21
>>230 >thisがconstなポインタとして扱われる
納得いたしました.
const T *foo;
とするとコンパイラは,
*foo, foo->
という記述に対してエラーを出すということと併せて.
>>204 の最初の二つは,
ポインタ * の読み方に似てるからどうにか自力で解りそう.
>>203 その本の著者が、
「そんなに難しい言語を解説しちゃう俺って天才w」
って読者に偉ぶってるだけ
「それでもメジャーになるくらいのメリットがC言語にはある」 っていう意味だろとマジレス
ぶっちゃけCマニア以外、コードを読めて、自分の思い通りのコード書ければどうってことない それだけのこと
effective C++は読むべき。 今読んでるけど、その辺のことも書いてあった。
>>235 は、inlineキーワードについてです。
inlineってデフォルトだと関数の実体が1KB以下ならインライン展開するんだっけ? VCだけ? それとも俺の勘違(ry
inlineについてはefficient c++の方が詳しいと思うぞ
240 :
190 :2006/02/18(土) 05:11:05
スレ違いを承知で, 恐れ入りながら申し上げます. Effective C++ って, 『Accelerated C++』 + 『プログラミングC++第3版』 のペアを放っておいてでも読むべき! といわれるほど内容が濃いのかなと, 半信半疑な私なのですが, 世間的にはどうなんでしょう.
それら2冊は「C++でプログラムを組む方法」を学ぶための本だけど、 Effective C++は「C++でより良いプログラムを組む方法」を学ぶための本であり、 「C++そのもの」の基礎については既に読者が理解している前提で書かれている。 だから「まだ自分は言語の基礎からして怪しいな〜」と思うなら、 その「ペア」をまずこなすべきかと。まぁ俺なりの意見として。
std::copyとmemcpyなんですが、皆さんはどういう基準で使い分けてますか? それともstd::copyに統一してたりするんでしょうか?
>>240 本読むの遅いか読む時間が無いと勘違いしてる人?
とりあえず流し読みでいいから全部目を通して、その後熟読するようにすると時間節約できるよ。
通勤通学の時間とかはあんまりおすすめじゃないけど、寝る前の1時間を読書だけに当てればその3つなら流し読みで
1週間かからないし。(全部理解するのでなくて何となくこんな事がこの辺りに書いてあったと覚える程度でいい)
>>242 memcpy()などのレガシーな関数は、ポインタを生で扱わないといけないようなとき以外は封印している漏れガイル。
247 :
190 :2006/02/18(土) 16:46:49
>>244 たしかに本読むの遅い方です.
PG本を買うときに不安になることで,
持ってる本に書いてあることとか, 熟読すれば気づけることとか,
「使ってりゃわかるでしょ」的なこととかが
つらつらと書かれてある本なのかもというのがある.
# とはいえさすがに 「プログラミング作法」を買うときは即買いだった.
『時間ねぇー!』とかそういうんじゃなくて.
このコードが、VC7.1で問題なく動くのですが、いいのでしょうか? //Primary Class template <typename T> class C { T value ; public : C(T const &val) : value(val) {} void print(void) { std::cout << "Generic value : " << value << std::endl ; } } ; //C<int>::print()だけを特殊化、ただし、わざとtemplate<>をコメントアウト //template <> void C<int>::print() { std::cout << "Specialized value : " << value << std::endl ; } main() { C<int> c(100) ; c.print() ;//問題なし } C++ Templatesという本によると、 メンバの特殊化にも、template<>プレフィクスをつけなければならないと書かれているのですが。
Hoge& foo = new Hoge; のようにnewしたインスタンスを参照で受けることはできますか。
>>249 俺のところではこういうことができた。
Hoge& foo = *new Hoge;
delete &foo;
だが、これがやっていいことなのかどうか分からない。
>>250-251 動作に問題は無いだろうが、可読性に問題があると思う。
std::auto_ptr<Hoge> p(new Hoge);
Hoge& foo = *p;
こんなんじゃダメなの?
>>248 g++ ではコンパイルできなかったので、よくない。
本題ではないが main() の戻り値を省略してるのもコンパイルエラーになった。
254 :
248 :2006/02/19(日) 00:25:19
>>253 やはりそうですか。
main()はもちろん、貼り付けるための省略です。
return書くと、一行増やさないと読みづらいですし。
VC++どうなっているんだろう。
メンバの特殊化には、template<>を省略してもおk
クラスの特殊化には、省略できない(でも、ちゃんと意図を認識できているようなエラーメッセージを吐く)
template<>がなくても受け付けるような、
文法のルールを実装していそう。
なんでメンバでは省略を許しているのか不明ですが。
255 :
248 :2006/02/19(日) 00:36:49
話は変わりますけど、main()でコンパイルエラーになるのはいいですね。
VCは以下が全部、問題なく通る……。
main() {} //まあ、K&Rだし
main() { return 0 ; } //これは、まあ、Cという歴史的理由で通るというのも分かるかな。
void main() {} //これはありえない。
int main() {}
ただこれは、禿の解説を見るに、問題なさそうなんですが。
ttp://www.research.att.com/~bs/bs_faq2.html#void-main >In C++, main() need not contain an explicit return statement. In that case, the value returned is 0, meaning successful execution. For example:
>>255 戻り値の省略は規格で認められていない。 VC が緩いようだ。
return の省略は禿の言うように規格で認められていて、動作も決まっている。
>>254 VC8.0 では、/Za で言語拡張をキャンセルすると、template<> のないメンバの特殊化体定義はエラー(C2906)になる。
258 :
248 :2006/02/19(日) 00:55:48
>>257 VC7.0と7.1も同じなようです。
MS独自のものだったんですか……。
Effective C++の第3版って日本語予定ありますか?
>>259 今のところ無かったはずだが
まだ店頭在庫で改訂2版置いてるところ結構あるから探して買うが吉
261 :
・∀・)っ-○●◎- ◆Pu/ODYSSEY :2006/02/19(日) 02:24:40
More〜の訳がマシなやつキボン
>>261 原文(英語)のも買えば解決。もしくは(ry
Effective C++の第3版はどうなってるか興味あるな (Boostの紹介があるのがすげえとか見たけど Boostとあろうものがそれくらいで歓喜するなよと) C++すっかり変わってしまったから
>>263 英語版を見る限り、boostに関する内容はないようだ。
templateに関する項目は確かに増えているが、これだけなら、
C++ Templatesの方がずっと詳細だし、やっぱりEffective
シリーズは初心者向けという色合いが強いように思える。
もちろん日本語版が出たらそれも買うつもり。
265 :
デフォルトの名無しさん :2006/02/19(日) 21:31:20
・どうやって、C++で作ったプログラムをUNIXでシステム化するのか。 ・クライアントがVCで、サーバがC++の時に、 どうやってデータのやりとりを行うのか。 ・なぜ、C++でOracleとの連携が取れるのか。 そういう情報が載っているサイトや本を教えて下さい。
釣り?
267 :
デフォルトの名無しさん :2006/02/19(日) 22:31:46
268 :
265 :2006/02/19(日) 23:12:34
釣りではありません。 本当にわからないので、知りたいんです。 ですから、勉強できる本やサイトが知りたいんです。
ネタにマジレスしてすまんな・・・
>>268 > C++で作ったプログラムをUNIXでシステム化
「プログラムをシステム化」って何だ?
> クライアントがVCで、サーバがC++の時にどうやってデータのやりとりを行うのか。
今まで一度も「クライアントがVC」なんて条件聞いたことないわけなんだが、
ま、普通にTCPとかUDPとかでいいんじゃない?
> なぜ、C++でOracleとの連携が取れるのか。
Oracleが外部にプログラムインタフェイスを公開してるからじゃない?
サイト調べるよりまずググり方学んできた方が・・・
釣り臭いポイント ・質問が複数ある。 ・どの質問も微妙にスレ違い。 ・VCとC++を違うものとして扱ってる。 ・一見、明確な質問のようだが、 よく見ると自分がどの程度わかっていて、 どういったことが疑問なのかさっぱりわからない。
総合すると エンジニア視点ではなく、ユーザ視点で見てる ってことかな・・・
>>271 だね。
>>265 意地悪するつもりはないが、俺たちじゃ君の力にはなれそうにありません。
まずは、書店にでも行って自分がわかるレベルの書籍を探してください。
全く同じtypedefを二度以上するのは問題ですか? たとえばこんなの typedef int Int; typedef int Int; VCだと全く何も言われないんだけど。
typedef って宣言扱いだっけ? 宣言なら何度でもOK 定義なら一回だけ。
275 :
265 :2006/02/20(月) 00:22:28
いや、基本はUNIXでC++で製造したプログラムがなぜ動くのかを知りたいんです。 自分は、ライブラリを作っているだけなのに、 何で動いているのかを知りたいんです。
>>275 ktkr!!!!!!!!!!!11111111111
トリつけろ、お前面白いwwwww
279 :
277 :2006/02/20(月) 01:16:16
マジレスした俺は負け組ですか?
>>275 の様子からするとやっぱり俺は
負け組ってことになりそうな予感・・・orz
>>275 まずはUNIXがなぜ動くのかから疑問に思え。
こんな天然物は最近珍しいな。大切にしようぜ。
複数のiteratorとかchar*とかをひとつのiteratorと見せかけれるものはありませんか? std::vector buf; void f(char* s, int n) { typedef std::istream_iterator<char> input_iterator; std::copy( input_iterator(source), input_iterator(), std::back_inserter(buf) ); // これと std::copy( buf.begin(), buf.end(), s ); // これを一回で済ませたいです } がんばれば自分で作れなくもないと思うのですが、標準やboostとかで用意されてるものがあればそちらを使いたいです
>>282 標準にはない。
Boostにもその機能そのものはなかったと思う。
>>282 boostにzip_iteratorというのを見つけた
>>282 std::vector<char> buf なら、別に char* にコピーする必要無いと思う。
>>284 zip_iteratorは282がやりたいことには使えない
>>282 その例ならそもそもsource.readを使ったら駄目なのか?
複数のイテレータをメンバに持って、それらすべてに同じ操作を適用するような multi_iteratorを書けばいいかもしれない。 boost/iterator_facadeあたりを使えば多少は楽に。 class multi_iterator : public boost::iterator_facade<...> { typename some::iterator& s; typename other::iterator& o; increment() { ++s; ++o; } ... }; クラステンプレートにすれば任意のイテレータを複数持てる。 イテレータの数を任意にしたければ、mpl/BOOST_PPでの自動生成で。 dereference()等ではstd::map()で返すとか。問題多そうだが。
質問者の最初の書き込みにすでにそういうことが書いてあった。駄レススマソ
>>287 istream_iterator<char>は空白を読み飛ばすから、readじゃ代用できない。
function_output_iteratorを使って書いてみた。使いかたに癖があってあまり便利じゃないかも。 template <typename T> inline void output(boost::tuples::null_type, const T &) {} template <typename Cons, typename T> inline void output(Cons &c, const T &x) { *c.get_head() = x; ++c.get_head(); output(c.get_tail(), x); } template <typename Tuple> struct replicator { replicator(const Tuple &t) : iters(t) {} template <typename T> void operator()(const T &x) const { output(iters, x); } private: const Tuple iters; }; template <typename Tuple> boost::function_output_iterator<replicator<Tuple> > make_broadcast_iterator(const Tuple &t) { return boost::function_output_iterator<replicator<Tuple> >(replicator<Tuple>(t)); } int main() { char *s = new char[1000]; std::vector<char> v; typedef std::istream_iterator<char> iic; std::back_insert_iterator<std::vector<char> > ins(v); char *p = s; std::copy(iic(std::cin), iic(), make_broadcast_iterator(boost::tie(ins, p))); }
gccのgompはどこからダウンロードできるのでしょうか?
branchの方に普通にあったと思ったけど?
たとえば、 sql_alias x1, x2; sql_expr expr = select( x1["a"], "b", "c", "d" ) .from[ inner_join( x1 = "table1" ), ( x2 = "table2" ), x1["a"] == x2["a"] ] .where( x1["a"] == _1 && between( "b", 1, 10 ) ) .order_by( desc( x1["a"] ) ); string sql4ora = gen_oracle( expr ); string sql4mssql = gen_sqlserver( expr ); みたいな、C++によるλライクなSQLジェネレータを作るとしたら 需要あるのだろうか?
たぶん漏れが知らないだけだろうけど、対象SQLサーバによらず同じコードですむ
(PHPでいうPEAR::DBのような)フリーのC++用データベースライブラリはほしいな。
>>294 お願い(*'-')人
>>282 これでいいじゃんw
BOOST_FOREACH(char ch, boost::make_iterator_range(input_iterator(in), input_iterator()))
{
buf.push_back(ch);
*s++ = ch;
}
>>282 これでもいいじゃん?
using namespace boost::lambda;
for_each(input_iterator(source), input_iterator()
, (bind(&std::vector<char>::push_back, &buf, _1), *var(s)++ = _1));
298 :
デフォルトの名無しさん :2006/02/23(木) 03:26:56
>>296 foreach.hppはどこで手に入る?
300 :
298 :2006/02/23(木) 06:19:08
foreachのソースは言語オタクにはたまらないんだろうが 俺にはさっぱりわからんw
テンプレートとかSTLとか全然使ってない。 std::sprintf()だけあればいいよ。って思うの俺だけ?
>>302 お前だけじゃないだろうが、自分の知らないことが世の中には
たくさんあることだけは忘れないようにしよう。
>>302 あなたがC++の何を使おうが、それはあなたの自由。
テンプレートやSTLを使う人間を否定さえしなければ問題ない。
>>302 せめてboost::formatにしようぜ。
再利用性考えまくったコードが一回でお蔵入りってのもあるけどな。
いや寧ろ、テンプレートを使えない香具師が必死になっているようにしか見えないのだが。 それはさておき、いつも迷うのだが文字列処理する関数は次のどれを引き数にとるべきかな? ・const char * ・std::string ・const std::string &
>>309 だれも必死になんかなってないだろ。
const std::string& がデフォルトだろうな。
std::string 渡すときもコストが低いし、
const char* のインターフェースを兼ねることもできる。
ただ、動的なメモリ確保に制限がある場合は const char* に
したほうがいいだろう。
std::string による値渡しは参照渡しに比べてメリットがあるとは思えない。
>>309 公に晒すならconst char*以外に有り得ない。
312 :
・∀・)っ-○●◎- ◆Pu/ODYSSEY :2006/02/25(土) 00:01:55
ここ最近WindowsのGUIベッタリなコードしかかいてない俺はLPCSTR
どうしてもって時以外はconst char*じゃね?
>312 最近というのならLPCTSTR(もしくはLPCWSTR決め打ち)じゃないのか? つまり、 普通はconst std::wstring & 訳ありの時はconst wchar_t * となる時代はいつの事やら。
315 :
・∀・)っ-○●◎- ◆Pu/ODYSSEY :2006/02/25(土) 00:44:33
std::basic_string<TCHAR>
316 :
309 :2006/02/25(土) 00:52:49
ふむ、考えてみたら文字列リテラル渡すこともあるからconst char *がいいのかな。 THX!
const std::string& には文字列リテラル渡せますよ、と。
そこでメモリの動的確保が問題になりますよ、と。 既に書かれているわけですな。
どうしても気になるときにはこんなこともする。 void hoge(const char*); inline void hoge(const std::string& s) { hoge(s.c_str()); }
class StringOrPtr { public: StringOrPtr(const char* p) : p_(p) {} StringOrPtr(const string& str) : p_(str.c_str()) {} operator const char*() const { return p_; } private: const char* p_; }; なんてのを作ったが、見た目が気持ち悪かったので使わなかった。
>>320 stringの寿命がわからんところで使って死にそうなコードじゃね。
可変長引数辞退忌避してるからなぁ。 vargsって過去互換以外でつかうか?
printf類自体は代わりにboost::formatもあるしな。
以前Effective C++が欲しいと言ってたものです。 紀伊国屋のサイトで購入できました。(店舗から取り寄せ) 私の検索時であと3店舗、今はあと1店舗しか残ってなさそうなので 他に興味がある方はお早めに。
boostは無駄が多い
あれだけたくさんのライブラリが入っているのに 「boost は」なんて一括りにして評価するのは バカか悪意を持ったものとしか思えない。
328 :
デフォルトの名無しさん :2006/02/25(土) 18:40:18
可変長引数は必要が有れば使う Javaでも後から追加になったくらいで 便利な機能だと思うけど・・
boost厨って何で必死なんだろうね
わろすわろす
333 :
デフォルトの名無しさん :2006/02/25(土) 19:34:32
グローバルで構造体を確保しています。 これをグローバルで確保せずにSTL使ってnewで確保しようと思ってます。 newの速度はどうなんでしょうか?
どうなんでしょうね。
335 :
デフォルトの名無しさん :2006/02/25(土) 19:48:22
new の評価結果の代入先がグローバルのポインタだったりしたらアフォだな
STLとnewの文脈上の関連がわからないんだが
337 :
デフォルトの名無しさん :2006/02/25(土) 20:20:28
new は言語の機能 STL はライブラリ STL は new の応用例
>>333 速度なんぞ気にせず使って良いと思う。
それが問題になることはまず無いはず。
>>336 newした構造体をvectorかなんかに突っ込むんでしょ。
…とすると
> STL使ってnewで確保しようと思ってます。
ってのは表現がおかしいな。
IQが20くらい違ってくると会話に支障が出てくるらしいぞ
ってことできっと
>>333 は未曾有の大天才なんだろう
340 :
デフォルトの名無しさん :2006/02/25(土) 20:55:57
クラス内のプライベート変数のポインタを外部に渡す関数を作ろうと思ってるんですが そんなことするのって設計としてあり?
NG。駄目駄目。ありえない。
プライベートメンバのハンドルを返すなんて信じられないわ!
constなポインタならOKなんじゃない?
>>340 constなポインタならまあありかもしれん。
345 :
デフォルトの名無しさん :2006/02/25(土) 21:21:54
const でも delete はできるからなあ・・・
>>343 はらわた曝す設計になってる時点で外部でconst外しがされると思われ。
ポインタ型の変数ではなく、「メンバ変数」へのポインタではないか? (もちろんメンバへのポインタでもない通常のポインタ
const外しの邪法を行う人間相手にはconst参照を返すメソッドも無力だからなぁ。 正直そんな腐った奴の面倒までは見なくて良いような気が。
349 :
デフォルトの名無しさん :2006/02/25(土) 21:31:43
そういう奴は private 破りもあっさりやりそうだな
350 :
デフォルトの名無しさん :2006/02/25(土) 21:31:53
constな参照返せば良いんでないかい?
>>350 はらわた曝す設計になってる時点で外部でconst外しがされると思われ。
352 :
デフォルトの名無しさん :2006/02/25(土) 21:36:13
こんな感じです。 class test { private: int test1[10]; public: int *GetTest(){ for ( int i=0; i<10; i++) { if ( test1[i] == -1 ) return &test1[i]; } return NULL; } } どうでしょうか?
353 :
デフォルトの名無しさん :2006/02/25(土) 21:37:56
参照のconstは外せないでしょ わざわざポインタ取り出せば、外せるけど それこそ、そんな奴の面倒まで見切れない
話がループしてるって。 >340よ、誓うんだ。二度とそんなことはしないと!
355 :
デフォルトの名無しさん :2006/02/25(土) 21:41:19
>>352 それだけなら別に可かと
test1[10]がお互いに・若しくは他のメンバと関係しあっているのなら不可
356 :
デフォルトの名無しさん :2006/02/25(土) 21:44:47
>355 理解力不足ですいません。ほかのメンバと関係しあっているのならってのは どういうことですか?
>>353 残念ながら外せます。
#include<string>
#include<iostream>
class human{
std::string name_;
public:
const std::string&name(){return name_;}
human(const std::string&name):name_(name){}
};
int main(){
human a("test");
const_cast<std::string&>(a.name())="a";
std::cout << a.name();
}
まぁconst外しする奴は腐ってるから面倒見なくても良いと思うけどなー。
>>352 >>355 の言ってる以外にも、
「空き」を意味するために、NULLと-1の両方を使ってるのが邪悪。
半年もたったら自ら使い方を間違ってささりそう。
constポインタを返すのは別にいいでしょ それをconst_castする香具師がボケなのであって、クラス自身は問題なしなはず
360 :
デフォルトの名無しさん :2006/02/25(土) 22:44:58
352です。 この使い方自体はconstでポインタを渡せば特に問題ということでいいでしょうか? ちなみに-1とNULLを使ってるのは意味があります。 class test { private: int test1[10]; public: const int *SetTest(int i_num){ for ( int i=0; i<10; i++) { if ( test1[i] == -1 ) { test[i] = i_num: return &test1[i]; } } return NULL; } } Test test; int *pNum; pNum = test.SetTest(10); if ( pNum != NULL ) { // 操作するときはこんな感じ } のような使い方をしようと思っているのですがどうでしょうか? この中のintをSTL・newとかを使って管理しようかなと思ってます。
>>360 全体が分からないからなんだけど
その「操作」ってやつをTest内で実装すれば内部を晒すこともない
設計が良くない感じはするね
いや、-1とNULLに意味があるのはわかる。 わかるけど、後々使い方を間違えやすい実装だよ、と言ってるわけ。 もし、test.SetTest(-1)ってやったらどーなるの? 悪いこと言わないから、せめて、アサーションくらい入れときましょう。 const int *SetTest(int i_num){ assert(i_num != -1); for ( int i=0; i<10; i++) もっと言うなら、空きがあるかどうかを記録するための配列を、 値を保持する配列とは別個に持った方が良いと思うよ。 そうすれば、使ってる側は、格納する値が-1かどうかは気にせずに済むから。
363 :
デフォルトの名無しさん :2006/02/25(土) 23:00:23
int *pNum; pNum = test.SetTest(10); if ( pNum != NULL ) { // 操作するときはこんな感じ } はどこでも行われる可能性があると思っていただいたほうがいいです。 Test testはシングルトンで扱っていろんなとこから値がセットされて いろんなとこからいじる可能性があります。
364 :
デフォルトの名無しさん :2006/02/25(土) 23:18:05
>>356 例えば、class testがメンバ変数「int a」を保持していたとして
aとtest1[10]が依存しあっているのなら・・・・の意です。
>// 操作するときはこんな感じ ここには具体的には何が入るの?
366 :
デフォルトの名無しさん :2006/02/25(土) 23:38:08
class test { private: typedef struct { int flag; int point; }T_TEST test1[10]; public: const T_TEST *SetTest(int i_num){ for ( int i=0; i<10; i++) { if ( test1[i].flag == -1 ) { test[i].point = i_num: return &test1[i]; } } return NULL; }; }; Test test; // これはシングルトンで扱う // 以下はいろんなところで使う----------- int *pTest; pTest = test.SetTest(10); if ( pNum != NULL ){ pTest.point++; } いろいろ変更してこんなかんじにしましたがどうでしょう?
367 :
デフォルトの名無しさん :2006/02/25(土) 23:38:40
>>360 素直に、vector<int>じゃダメ?
全角托イ
369 :
デフォルトの名無しさん :2006/02/25(土) 23:46:03
ウホ帰れ うんこ臭いんだよ
ちょ、ちょっとまて。
フラグを用意したのはOK。でも、なぜフラグまで外部にさらす?
あと、値を変更させるつもりならconstポインタは使えないから・・・
それと、pTestの型はどっちみち間違い。
俺に3行変えさせてくれ。
int *SetTest(int i_num){ ← ここ
と
return &test1[i].point; ← ここ。
と
if ( pNum != NULL ){ *pTest++; }
>>360 STLのvectorを使うなら、サイズ変更でメモリの再割り当てが起きたときのことも考えておかないとダメ。
Σ(゚Д゚;)やべ。 3つめは if ( pTest != NULL ){ *pTest++; } の間違い。
372 :
デフォルトの名無しさん :2006/02/26(日) 00:04:30
366と360は同一人物なのでよろしく、もう一度書きます。 class test { public: typedef struct { int flag, point, money; }T_TEST; private: T_TEST test1[10]; public: T_TEST *SetTest(int i_point, int i_money){ for ( int i=0; i<10; i++) { if ( test1[i].flag == -1 ) { test1[i].point = i_point; test1[i].money = i_money; return &test1[i]; } } return NULL; }; }; Test test; T_TEST *pTest; pTest = test.SetTest(10); if ( pNum != NULL ){ pTest.point++; } フラグまで外部に晒すのは構造体のメンバが複数あるので結果的にフラグも 見えてしまう状況はいたしかたないと思ってます。
> 366と360は同一人物なのでよろしく、もう一度書きます。 すまそ。 > フラグまで外部に晒すのは構造体のメンバが複数あるので結果的にフラグも > 見えてしまう状況はいたしかたないと思ってます。 いたしかたなくない。 typedef struct { int point, money; } T_TEST; typedef struct { int flag; T_TEST data; } T_DATA; ついでを言えば、flagの型もintよりboolの方がよいとは思うが。
374 :
341 :2006/02/26(日) 00:20:42
>>372 SetTestがダサい。メソッド名から
・未使用のT_TESTを検索する
・それにi_numをセットする
と二つのことをしていることが読み取りにくい。(Testをセットしているんじゃないし)
375 :
341 :2006/02/26(日) 00:23:31
やるならせめて class test { private: typedef struct { int flag; void setPoint(int i_num){ point = i_num; } private: int point; }T_TEST test1[10]; public: const T_TEST *getTest(int i_num){ for ( int i=0; i<10; i++){ if ( test1[i].flag == -1 ){ return &test1[i]; } } return NULL; }; }; Test test; // これはシングルトンで扱う T_TEST *pTest = test.getTest(); if ( pNum != NULL ){ pTest->setPoint(10);} くらいしなきゃ。コンパイルしてないしかなり詰めも甘いけど。
376 :
341 :2006/02/26(日) 00:27:08
うわ、コピペ元間違ってんじゃん。 T_TEST *pTest = test.getTest(); if ( pTest != NULL ){ pTest->setPoint(10);} だな。なんかいつの間にかパラメータも増えてるけど…。
377 :
デフォルトの名無しさん :2006/02/26(日) 00:36:21
>375 private: int point; }T_TEST test1[10]; の部分なんですがこのところでメンバが多くなって10個ぐらい増えた場合に 単純にセッターを10個増やすことになると思いますがそれはC++では普通にやる ことなんですか?
378 :
デフォルトの名無しさん :2006/02/26(日) 00:37:04
リファレンサ・クラスを作るだな
379 :
341 :2006/02/26(日) 00:46:19
必要なら作るべき。けど普通そこまでにはならないと思う。 外部からset、getとか頻繁にし過ぎるようだったら設計が悪い。 あまり多くのメンバが追加されるようなら T_TESTがする仕事が多すぎないかとか、 分割した方がいいか検討しなきゃな。
380 :
デフォルトの名無しさん :2006/02/26(日) 10:39:20
リファレンサ・クラスとはなんでしょうか? 検索でもあんまりひっかからないので教えて
381 :
cccc :2006/02/26(日) 10:47:51
VC6.0 アドレス、A、Bが分かっていて、AからBまでをファイルに書き出す方法は、 ありませんか?
>>381 copy((char*)A,(char*)B,std::ostreambuf_iterator<char>(stream));
383 :
デフォルトの名無しさん :2006/02/26(日) 12:31:12
stream.write((char*)A, (char*)B - (char*)A);
384 :
デフォルトの名無しさん :2006/02/26(日) 12:35:37
http://www.open-std.org/jtc1/sc22/wg21/ News 2006-02-26: The C++ Standard Library Issues List (Revision 41) is available (.tar.gz)
News 2006-02-26: C++ Standard Core Language Issues List (Revision 40) is available, also committee version
>>382-383 なんでわざわざわかりづらいコード書くんだよ。
VCって言ってるんだからWin32のAPI使えばいいだろ。
WriteFile(fileHandle, A, B-A, &bytesWritten, 0);
複雑なマクロが書けるとかテンプレートが使いこなせるとか、
マニアックなコードで短い行数で書ける奴が偉いなんて時代は
2002年頃までに終わってるんだよ。
ネタだよな?
>>385 たしかに382-383は不親切な回答だと思ったかもしれないが、
ここはC++のスレなんだからC++の標準ライブラリでの方法を答えるのが筋だろ。
明らかに
>>381 が
>>1 読んでないの分かってて書く
>>382-383 も
荒れる原因作ってるだけだろ。どのヘッダをインクルードすればいいのかとか
また質問しに来たらどうすんだか
390 :
デフォルトの名無しさん :2006/02/26(日) 17:55:43
何喧嘩してんだ 低能同士仲良くしろよ
>>390 よそのスレで馬鹿にされたからって
八つ当たりすんなよw
394 :
デフォルトの名無しさん :2006/02/26(日) 18:36:10
C++のオブジェクトをP2Pのような相互通信するオブジェクトと捉えて プログラミングしようと思ってるんですが、ナカナカ上手くいかないっす(涙 基本的には、 1. 各機能オブジェクト間で状態遷移を通知し合う。 2. 各機能オブジェクトは上位のオブジェクトに保持されるが、上位のオブジェクトがすることは、各機能オブジェクトに、さらに上位から送られてきた命令を分散するだけで一切実際の処理はしない。するとしても初期値設定ぐらい。 boost::signalあたりで実装はしてみたんですがイマイチスマートに書けないんですよね。 …わけわからんこと言ってすいません。
>>394 STL スレは統合していいと思うけど Boost はなあ。
時期標準といっても案件によっては使わせてくれない場合も多いし・・・。
>>395 もうちょい「上手くいかない」の内容とか
各機能がなんなのか書けば誰か助けてくれるかもよ。
…>390みたいなやつも紛れ込んでるけどさ。
class Aの中でclass Bのインスタンスを一個だけ使うような場合ってどうしてますか? class A { B b; }; ってするか、 class A { A() {b = new B:} ~A() {delete b;} B *b; }; ってするか。 上の方が簡単だけど、Bのコンストラクタに引数があると困る。
はぁ?
>>398 class A {
B b;
A() :b(...) { ... }
};
とりあえず最初はBが ・値オブジェクトなら先の方、 ・参照オブジェクトなら後の方 でやっちゃうかな。まぁケースバイケースだけど。
403 :
402 :2006/02/26(日) 19:39:46
ところで俺>341なんだけど、 >352の彼は問題解決したのかなぁ。 どうなったか書いてくれんと落ち着かない…
>>401 それってBがAの基底クラスじゃなきゃおかしくね?
>>352 は
test1の定義を、int *test1にして
コンストラクタでtest1 = new int[10];すればOK。
インスタンス1つならstatic int test1[10];でもいい。
セッタなんてマンドクセ
407 :
デフォルトの名無しさん :2006/02/26(日) 20:36:46
バリアント型を使用したあとの、 メモリの解放ってどうやればいいんでしょうか? なんか呼び出すたびにメモリ使用容量が増えている気が・・
#include <iostream> #include <functional> #include <boost/function.hpp> struct SomeObject{ void Do(int) { std::cout << "hogehoge" << std::endl; } }; int main(){ SomeObject t; boost::function<void (int)> g = std::bind1st( std::mem_fun(&SomeObject::Do), &t ); g(0); return 0; } だとコンパイル通って、 struct SomeObject{ void Do(void/* ここと */) { std::cout << "hogehoge" << std::endl; } }; int main(){ SomeObject t; boost::function<void (void/* ここと */)> g = std::bind1st( std::mem_fun(&SomeObject::Do), &t ); g();/* ここを変更 */ return 0; } だと通らなくなるんだけど…理由わかる人がいたら教えてもらえませんか? 環境はVC2005Express + boost 1.33.1です。
>>408 std::bind1stは二引数の関数オブジェにしか使えない。
bind1stは2引数の関数オブジェクトにしか使えないという糞設計だから。 boost::bindを使いましょう
>>409-410 マジthxですm(_ _)m
bind1stは二引数関数オブジェクト専用だったんですね(汗
一応動いたコード
#include <iostream>
#include <functional>
#include <boost/bind.hpp>
#include <boost/function.hpp>
struct SomeObject{
void Do(void) { std::cout << "hogehoge" << std::endl; }
};
int main(){
SomeObject t;
boost::function<void (void)> g = boost::bind( std::mem_fun(&SomeObject::Do), &t);
g();
return 0;
}
>>411 -boost::function<void (void)> g = boost::bind( std::mem_fun(&SomeObject::Do), &t);
+boost::function<void (void)> g = boost::bind( &SomeObject::Do, &t);
でいいよ
>>412 本当だ、普通にコンパイル通った…。
mem_funまでやってくれるんだ…すごい…。
>409 オブジェワロタ
同じクラスであればunionを使うのは問題ありませんか? 座標を示すx,y,zという値があり、場合によってはdata[0]〜[2]のように 配列っぽくアクセスしたい場合があります。 x,y,zはPOTではなく、関数なども持つクラスだとして、以下のように unionを使うのはOKでしょうか? union { { foo data[3]; }; { foo x,y,z; }; }; unionがメモリの内容を複数の解釈をするっていうものであるならば、 問題はない様な気がしますが。
>>415 構造体の各要素の配置は規定されてなかったと思う。
だからおそらくだめ。
>>415 配置以前に、規格上「コンストラクタを、デスクトラクタ、コピー代入演算子を定義したクラス型はunionのメンバにできない」となっているから、
基本的にはPOD型じゃないとダメかと。
418 :
デフォルトの名無しさん :2006/02/26(日) 22:55:26
>>415 foo data[3], &x = data[0], &y = data[1], &z = data[2];
あるいは
foo x, y, z, *data[] = { &x, &y, &z };
*data[0] のように * がつくが、
「配列っぽく」という要求は満たす
目的の為なら手段を選ばず。 struct { foo x,y,z; foo& operator[](int i) { switch(i)/*以下略
次は俺の出番か?
>419 わりと普通じゃんと思ってしまう俺はもうJavaには移れませんか、そうですか
>415 名前にちょっとかっこが付くけど、普通にこんなんじゃ駄目か? struct bar { foo data[3] foo &x() {return data[0];} 略
C++なら424でも十分
〃〃∩ _, ,_ ⊂⌒( `Д´) < だって括弧ヤダヤダ! `ヽ_つ ⊂ノ
そこで#define x x()で(r
ここで変態的なのを出してみる。 struct bar { foo x,y,z; foo& operator[](int i) { static foo bar::* hage[] = {&bar::x,&bar::y,&bar::z}; return this->*(hage[i]); } };
あやまれ! ツルッパゲのオッサンにあやまれ!
平成18年2月27日、2chム板C++相談室 part47スレッドを訪問した際、 ツルッパゲのオッサンの方に、私は不遜な対応をし、同氏の名誉を傷つけ、 またご迷惑をおかけしました。心よりお詫びいたします。 自身の軽率で傲慢な言動を恥じ、深く反省しております。 今後は、常に自分の立場をわきまえ、念頭に置いた行動をとりますことをお誓いいたします。 二度とこのような失態を招かない所存にございますゆえ、 このたびに限り、寛大なるご措置をお願い申し上げます。
>>429 const 忘れてるよ。付けても最適化してくんないみたいだけどね。
- static foo bar::* hage[] = {&bar::x,&bar::y,&bar::z};
- return this->*(hage[i]);
+ static foo bar::* const bjarne[] = {&bar::x,&bar::y,&bar::z};
+ return this->*(bjarne[i]);
434 :
・∀・)っ-○●◎- ◆Pu/ODYSSEY :2006/02/27(月) 01:29:53
タブクリア吹いたwwww
435 :
・∀・)っ-○●◎- ◆Pu/ODYSSEY :2006/02/27(月) 01:56:18
Cスタイルの初期化は出来なくなるがこんなのどう? struct Point3D { float &x, &y, &z; float data[3]; Point() : x( data[0] ), y( data[1] ), z( data[2] ) { } //以下略 };
でも俺なら
>>435 にするけどなあ。
>>419 ,
>>429 のやつだと、
data[0], data[1], data[2]が順に等間隔で並ばない可能性があるから、
いつかハマりそう。
static int hoge[60] みたいにstaticを使って動的にメモリを確保できないのでしょうか? つまり x=60; static int hoge[x]; みたいなことがしたいんですが
>>438 staticがどの意味のstaticなのかわからん。
静的なのに動的とはこれいかに? ソースコードを書き換え→コンパイラを起動→実行
どうも動作がむちゃくちゃおかしいので、一応確認しておきたいのですが typedef struct{ char* txt[16]; }TS, *LPTS; void testcode( void ){ TS ts; char* smptxt = "abcdefghijklmn"; ts.txt[0] = smptxt; ts.txt[1] = smptxt; ts.txt[2] = smptxt; } みたいなコードで、ts.txt[0]への代入後、どうもts.txt[1]以降の内容も変化 変化した内容は[1]が0x68676665、[2]が0x6c6b6a69とのことなので、 どうやらsmptxtの文字列が突っ込まれているようです VC++2003の問題だとは思うのですが、もしかして何か俺の方でやっちゃってます?
>>443 なんだかわかんないのだけれども、
[0]のところにブレークポイントしかけて、
その時点で[1]と[2]の中身も変化してしまうということ?
>>443 そのテストコード、VC++2003で試してみたけど、正常に動作したよ。
(testcode(void)の最後にprintfで表示させてみた)
ts.txt[]の参照文字列を表示させても同じだし、ts.txt[]の指しているアドレスを
確認したけど同じだった。
別のところに問題があるんじゃないの?
446 :
443 :2006/02/27(月) 17:23:29
>>444 その通りです
[0]への代入のところにブレークポイントを置いてチェックすると
[0]への代入時に[0]にはsmptxtのアドレス、[1]以降に変な値が入ってます
今確認してみたところ、[1]への代入、[2]への代入時には[1]以降のデータは変化してないっぽいです
>>445 うーん…
新しいプロジェクトで同じことやっても同じ結果が出てるんですよね…
(=ビルドオプションの類の問題じゃなさそう)
となると、バージョンか開発環境の設定?
447 :
445 :2006/02/27(月) 17:38:38
>>446 ちなみに、コンパイラのバージョンは最適化コンパイラで13.10.3077(for 80x86)
コンパイルは、コンソールからなにもオプションつけないで、clでやっている。
(コマンドラインアプリとして、mainくっつけて実行)
>>443 ts.txt[0]への代入直後、ts.txt[1], [2]の(初期化および)代入以前の状態だと
ts.txt[1], [2]の値は不定だから。
…なわけないよな…。
参考までに、g++3.4.2では、ts.txt[0]代入前後で[1], [2]の値に変化はなかったよ。
449 :
415 :2006/02/27(月) 21:24:51
いろいろと参考になります。
クラスはunionにできないんですね。
x,y,zへのアクセスとdata[0]〜[2]へのアクセスのコストが等しくなる
方法がいいんですが、
>>419 ならインライン展開されると見て大丈夫ですか?
初期化の際に多少コストがかかるのは問題ないです。
インライン展開されるかどうかなんて環境によるだろ
俺はVC++8.0に __forceinline を指定して、極力
インライン展開を使用するようにして使っているが、例えば
>>435 を
使っても使わない時と比べ5clockほどしか増えない。
5clockw
インライン関数はどうでもいいが、何でもかんでもvirtual付けたがる奴いるよな。 重いんだよ。絶対継承される自信があるときだけにしてくれ。
何も継承していないし、 どこからも継承されていないクラスは、 コンパイラの最適化で、virtualを外せないものなのかな。 というか、デフォルトでvirtualで、必要のないものだけ、 コンパイラが判断してvirtualを外すという仕様はどうだろう。 Dが確か、そういう仕様だったはず。
455 :
454 :2006/02/27(月) 23:45:00
もちろん、継承されていても、virtualを外せる場合は結構あると思うんだけど。
456 :
・∀・)っ-○●◎- ◆Pu/ODYSSEY :2006/02/27(月) 23:47:28
問題はfloatごときに同じ数だけアドレス型の領域が増えるのが効率が悪すぎることだ。
>>454 その D の仕様では virtual テーブルまで消えるのか?
単に呼び出し時に virtual テーブルを経由せずに呼び出すことを
「virtualを外す」って言ってるだけじゃないの?
もしそれだけなら、 C++ でも最適化の範囲内で可能。
>>454 Dの仕様書ではこうなってた。
>コード生成時にDはクラス階層を全て把握していますので、
>オーバーライドされていない関数への呼び出しは全て最適化されて non-virtual になります。
こういう言語ではvtableは常に作るのかな。デストラクタは常にオーバーライドされるし。
459 :
454 :2006/02/28(火) 00:26:42
C++は、やはり速度優先といった感じがしますね。 自分の考えとしては。 vtableがあるというだけでは、vtable分のサイズと、 vtableへの参照だけなので、 int型のメンバ変数ひとつのクラスを何十万と作るわけじゃなければ、 別に気にしなくてもいいんじゃないか、などと思えてしまいます。 それでも、JAVAや.NETまで、思い切ることができない性格ですが。
はじめまして、現在VC++2003を用い開発をしているのですが、 Win32コンソールアプリケーションからWin32DLLを動的に明示リンクした際に、 なぜかReleaseでのみ問題が発生します。 DLL側は __declspec(dllexport) int LL_OpenArchive(LPCTSTR szFilePath) { return s_osaArcEx.OpenArchive(szFilePath); } の様に宣言しており、もちろん定義ファイルでエクスポートを定義しております。 アプリケーション側は typedef int (__stdcall *LL_OpenArchive)(LPCTSTR); の様にプロトタイプ宣言を行いLoadLibary, GetProcAdressを用い関数のアドレスを取得しています(そこまでは問題有りません) 取得した関数に引数としてchar s[512]の様な固定長CHAR配列にgetsで文字列を取得したものを当てています。 が、Releaseビルドでその処理を行うと、sのアドレスが4バイト引かれるのです。Debugではおこりません。 ためしにDLL側の関数の中身をreturn 0;のみにしたりもしましたが状況は変わりませんでした。 このようなことはあり得るのでしょうか? またどう対処すればよろしいのでしょうか? ご教授お願い致します。
>>460 よくある。対策は↓
コンパイラの、プログラム全体の最適化 (/GL) を一回はずしてリビルド。
終わったらもう一回有効にして再度リビルド。
誰かが言わなくちゃいけないから俺が言う。 >460 回れ右して初心者スレかWin32APIスレにGo!
>454 お前のちっぽけな価値観だけで、 偉大なるC++をどうこうしたいと妄想するなんて片腹痛い。
宣言だけが記述されたヘッダと、(実装をコンパイル済みの)オブジェクトファイルしかない状況でも virtualは付け外しできるのかな。 そのオブジェクトファイルは、他の(CやFortranなどの)言語でも使用される一般的なツールでリンクできるという条件で。 可能なら、継承されててもnon-virtualにできる選択肢を残した上で、virtualは自動化してもらえれば便利だね。
C++の本でいいのはどれでしょう? ASCIIの「C++言語入門」は持ってますが古い規格なので 最近新しく探しているのですが、これはと思ったのは分厚く 7000円もするので買うのを躊躇しています。 リッチー&カーニハンの「プログラミング言語C」のような 解説書を探しています。 よい本がありましたら教えてください。
>>466 プログラミング言語C++がC++版K&Rと言われてる
俺が他にお勧めするのは、Accelerated C++
後はもう店頭在庫のみだがEffective C++
>>466 古い規格での標準C++の勉強は終わっていて、7000円は高すぎて禿げてしまうというのなら
標準規格はIS、FDIS(
>>5 )を参照するという手もある。
>>460 スレ違いだがあえて答えてやろう。
エクスポートしてる関数にも_stdcall付けやがれ。
470 :
460 :2006/02/28(火) 11:04:01
スレ違いだったにもかかわらず教えて頂きありがとうございました。 結果的には__stdcallのつけ忘れでした 初歩的orz 相談室と書いてあったので早とちりしてしまいましてご迷惑おかけしました。 ありがとうございました。
>>454 多くの C++ コンパイラはコンパイル単位でしか最適化しないので
そーゆー、複数のコンパイル単位間での最適化は
望むべくもなく。
472 :
466 :2006/02/28(火) 21:12:31
>>467-468 ありがとうございます。
教えていただいたタイトルを頼りに本屋を渡り歩いてみます。
レスが遅くなりましてすみませんでした。(今帰宅しました)
International Standard は詳しくて良さそうですね。
あんまり英語得意じゃないんですが、日本語版の本を購入
するまでは頑張ってこちらで勉強してみます。
C++でBCDを使うためのノウハウみたいなのが紹介されてる本やサイトってありますかいね?
475 :
デフォルトの名無しさん :2006/03/01(水) 01:11:46
>>475 内部向け ってだけで「会員専用」の意ではない。
根っからのtemplate hackerの俺としては今後コンソールアプリを作るとき以下のようにmainを書こうと思うのですが、おまえらやC++規格的にはアリですか? とりあえずVC++2005EE的にはアリのようです #include <iostream> #include <typeinfo> template<class char_t> int main(int argc, char_t* argv[]) { std::cout << typeid(char_t).name() << std::endl; return 0; } namespace startup{ //int main(int argc, char* argv[]) コメントアウトとかして切り替える //{ // return main<char>(argc, argv); //} int wmain(int argc, wchar_t* argv[]) { return main<wchar_t>(argc, argv); } } mainとかwmainをnamespaceとかにいれてイイノカナー
>>477 #if defined(UNICODE) とかで切り分けろバカw
あと、main や wmain はnamespaceいれちゃダメ。
>>478 UNICODEって標準じゃなくてWindowsSDKで使われてる識別子じゃなかったっけ?
>>479 そうだけど、_UNICODEだって独自のものだから、どっちもどっち。
UNICODE も _UNICODE も何のことだか分からない俺。
てか、windows 以外で wchar_t ベースの main に対応してる環境なんてあんのか?
struct base { base() {} virtual ~base() {} }; template <typename T> struct derived : public base { typedef T member_type; T value; derived(T value) : value(value) {} }; template <typename T> base* derived_generator(T value) { return new derived<T>(value); } base* tmp = new derived_generator(1); このとき、tmpからmember_typeがintであることを知る方法はないじゃろうか…。 int value = dynamic_cast<derived<int>*>(tmp)->value; とすればvalueはとれるんじゃが、型がintだと明示したくないのじゃ。 TYPE obtain() const { return dynamic_cast<derived<TYPE>*>(tmp)->value; } このTYPEはderived<TYPE>::member_typeと等しいのじゃが、どうにかして取り出せんもんかのう。 爺にはとんと見当がつかんのじゃ…。
base* tmp = derived_generator(1); じゃった。書き写さずコピペすればよかったのう…。
爺さん,無理だと思うよ. member_typeの型情報が必要な処理はderivedの中に入れるしかないよ
>>483-484 それができないからこそ、boost::anyにはany_castがあり、次期C++にはautoが導入される
あるいは型情報を外に出すとか typedef int My_Type; struct base { base() {} virtual ~base() {} }; template <typename T> struct derived : public base { typedef T member_type; T value; derived(T value) : value(value) {} }; template <typename T> base* derived_generator(T value) { return new derived<T>(value); } typedef derived <My_Type> My_Derived; int main () { base* tmp = derived_generator(1); My_Type value = static_cast<My_Derived*>(tmp)->value; return 0; } 爺さんこんなのはどうだい?
>>486 これはautoで解決できる問題じゃないと思う。
autoで思い出したんだが、auto型のメンバ変数は許可されるのだろうか? その辺詳しい人いたら教えてけれ(´・ω・`) struct Hoge { auto value_; template <class T> Hoge(T v) : value_(v) {} }; こんな構造体を書いた時、 Hoge h(int(10)), h(double(1.0)); な風に使ってしまうと、テンプレートのようにHogeに複数の実体が作られるのかどうか…
暗黙の型変換付のboost::anyとか struct base{ struct inner_base{ virtual inner_base*clone(){return new inner_base;}; virtual ~inner_base(){} }; template<typename T> struct inner_derived : inner_base{ typedef T member_type; T value; inner_derived(const T&value):value(value){} inner_derived*clone(){return new inner_derived(value);} }; inner_base*value; template<typename T>base(const T&value):value(new inner_derived<T>(value)){} base(const base&value):value(value.value->clone()){} base&operator=(base b){swap(b);return *this;} base():value(new inner_base){} ~base(){delete value;} void swap(base&b){inner_base*p=value;value=b.value;b.value=p;} template<typename T>operator T&(){return dynamic_cast<inner_derived<T>&>(*value).value;} }; #include<iostream> int main(){ base tmp=1; int value = tmp; std::cout << value; }
>>485-490 爺に教えてくれて感激じゃ…。じゃが、やはり標準C++では無理なことかのう。
>>487 のようにしてしまうと、
derived_generator(1);
この関数テンプレートは、引数の型を判別して derived<int> のインスタンスを生成するのに
別の場所でintだと明示しないとならないのは厳しいのう。
と思うたら
>>490 これはすごいことじゃ…天狗じゃ…天狗が現れおった…!!
爺の用途には暗黙の型変換でも十分じゃ。じっくり読むだえ。
>>489 要らないと思う。
クラステンプレートとそれを生成するテンプレート関数でいいだろ。
class HogeState; void change( HogeState* new_state ); class HogeState{ int ahe, uha; public: void foo(){ change( new HogeState ); ahe = 777; } void foo2(){ ahe = 888; change( new HogeState ); } }; HogeState* state = 0; void change( HogeState* new_state ){ if( state ) delete state; state = new_state; } int main(){ HogeState hoge; hoge.foo(); hoge.foo2(); return 0; } foo()では、自分がdeleteされた後にaheに代入し、しかもエラーが出ませんが、これはOKなんでしょうか? foo()が駄目だとしたら、foo2でも危うい気がするのですが、実際どうなんでしょう。 無理矢理1ファイルに書いたら意味のないコードになってしまいました。ご容赦を。
>>493 > change( new HogeState );
newで新しく確保して、それを渡しているだけ。hoge関係なし。
> if( state ) delete state;
deleteにNULL渡しても問題ないからif(state)は意味ない。
deleteで開放しているのはさっき新しく確保したHogeStateであってhogeではない。
> state = new_state;
仮引数に代入した所で意味はない。
なんか大混乱コードだなぁ。
495 :
493 :2006/03/02(木) 19:18:19
本当だ、なんだこれは…。申し訳ないです、元はこんなのでした。 class Hoge{ //Hoge.h-------------------------------- HogeState* state; public: Hoge(){ state = new HogeState; } void changeState( HogeState* new_state ){ delete state; state = new_state; } void foo(){ state->foo( this ); } void foo2(){ state->foo2( this ); } }; class Hoge; //HogeState.h--------------------------- class HogeState{ int ahe; public: void foo( Hoge* hoge ); void foo2( Hoge* hoge ); }; #include "HogeState.h" //HogeState.cpp--------------- #include "Hoge.h" void HogeState::foo( Hoge* hoge ){ hoge->changeState( new HogeState ); ahe = 777; } void HogeState::foo2( Hoge* hoge ){ ahe = 888; hoge->changeState( new HogeState ); } #include "HogeState.h" //main.cpp-------------------- #include "Hoge.h" int main(){ Hoge hoge; hoge.foo(); hoge.foo2(); }
>494 仮引数? > さっき新しく確保したHogeState ちがわね?
>>495 > ahe = 777;
deleteされたインスタンスに対してメンバ変数に変更を加えてるのでダメ
> ahe = 888;
deleteされる前に触ってるからOKだけど
直後のchangeStateで触ったインスタンスはdeleteされるので意味なし
じゃないかな?
498 :
493 :2006/03/02(木) 19:50:12
497さんレスありがとうございます。 デリート済みインスタンスの関数であっても、 メンバにアクセスしなければ大丈夫、という結論でよろしいのでしょうか。 メンバ関数であっても、所詮は関数という感じでよさそうなのですね。
エラー・例外が出ないから大丈夫、というのは個人的にはあんまり好きではないな。 メンバ関数にはthisポインタが渡されるだけで、あとは確かに通常の関数とほぼ同じだが thisポインタが無効になった時点でそれ以上そのクラスオブジェクトは仕事を続けるべきではないと思う。
500 :
475 :2006/03/03(金) 03:43:39
今アクセスしたら認証要求が出たよ・・・ やっぱりダメだったんだろうな。
このスレに書いたからだろw
std::exceptionやstd::runtime_error等の例外クラスの wchar版はなぜ提供されないのでしょうか? std::wexceptionとかstd::wruntime_errorとか
>>502 俺はwcerrなんかのワイド文字ストリームがマルチバイト文字へ変換する仕様だからだと思っている。
その変換処理の最中に例外を投げたくなるようなことになったら、どうしようもなくなるだろうと。
単純に、例外の中で例外を投げればって思った俺は駄目ですか?
505 :
503 :2006/03/03(金) 18:34:00
>>504 俺は例外が発生している最中に例外が投げられることを問題に思っているのではなく、
エラーメッセージが表示できないことだと思っている。
もちろん画面への表示という行為も失敗するかもしれないけどさ。
>>502 wchar_t 版がない理由は知らんが、char版でもUTF-8をブチ込むことは許されてるからそれで我慢汁カウパー。
507 :
デフォルトの名無しさん :2006/03/04(土) 00:28:50
コンストラクタ は、protectedに, デストラクタは、virtual で public に というクラス定義がありますが、これは どういう理由でこのようにしているのでしょうか?
>>507 インターフェースとして使うように設計されていて、
実際に new などで生成されるのは派生クラスだけ
ということが想像できるが、作った奴に聞いてコメント書かせるのが正解。
>>507 継承して使え。と書いた人が主張している。
>>507 コントラはそのクラス変数の作成時に呼ばれる関数だから
作成されていないのに外部から勝手に呼ばれたら困る。だからプロテク。
デストラはそのクラス変数が破棄されるときに呼ぶものだが
途中で破棄したい場合に外部から呼ぶため。だからパブリ。
static なメンバ関数内で new するというパターンなんかもあるよ。
>>512 事前条件が厳しいときのファクトリーパターンであってますか?
>>512 それだとコンストラクタは private だろ。
もしかして、時代はwchar_tが普通で、 const char *とか書いてる自分は駄目なんじゃないか と怖くなる今日この頃、皆様はいかがお過ごしでしょうか?
vc8からはデフォルトでwchar_tだしな(UNICODE, _UNICODE)
まだ使ったこと無いんだけど、vc8ではsizeof(wchar_t)っていくつなの?
( ゚д゚)ポカーン
>>517 WindowsがUTF-16を使っているので、Windowsの処理系ではまず間違いなくsizeof (wchar_t)は2です。
>>519 さんくす。
sizeof(wchar_t)を4にするオプションがないかと期待したんだけど。
wchar_tを使っても可変長エンコーディングからは逃れられないのか。
>>520 仕様:「本ソフトウェアはサロゲートペアに対応していません。将来的にも対応する気はありません。」
>>519-520 確か、CodeWarriorなら Windows でも 4 == sizeof(wchar_t) だよ。
>>521 サロゲートペアが理解できないユーザーからクレームが来るくらいなら、
可変長エンコーディングを我慢したほうが精神衛生上良いかと。
>>522 クロス開発環境だからWindowsアプリは作れないけど、ってオチ?
>>522 フツーにWindowsアプリが作れますがなにか?
販売終了、サポート終了の製品を紹介されて、どうすれば?
おまいら書くとき何使ってる? 俺まぢでメモ帳。
>>527 そんなのもお構いなしで押し付けるのが信者という物です。
>>528 VSのIDEマンセー!
まあ、もうすこしインテリセンスがインテリになればいいんだけど。
簡単な実験をするときはxyzzyで書いてcl 普段はVSのIDE 味気ないなぁ
VS8重すぎ・・・ ファイル閉じるのに5秒くらいかかるよ・・・ 複数ファイル一気に閉じると1分以上待たされる というわけで、xyzzyに一票
流石に1分はまたないが、起動と終了に時間が掛かる。
2005は糞重いね
ただ、2回目からの起動が2003に比べて早くなってるね。 逆に言えばメモリに常駐してる部分が大きいってことかね。
>>536 ハァ?
ドトネトで、ネイティブコードのキャッシュが残るから、
二回目から起動が早くなるんだろう。
急ぎ働きのときはcat、 ちょっと編集するときはvi、 腰据えて作業するときはXyzzy、 他人に見せるときは桜エディタ。
スレ違いの流れに疑問を口にしないお前らに失望
>他人に見せるときは桜エディタ。 なぜなんだか、とても気になる
>>539 そうだよな
お前らマでやれよ
emacs
ワロスww
std::mem_fun()の使い方が今一よく判らん。
って話はSTLスレ向きかな。
>>540 Xyzzyはフォントを小さくしているしタブや2バイト空白が見える設定にしているから
他人には(特に老眼入ってる連中には)激しく読みにくいらしいから。
どうせ普段使わないからってことで、キーワードの色付けも自分の好みよりも派手にしてある。
ある構造体型が定義されているのですが、 そこには typedef struct tagStructName : public tagHogehoge{ /* tagHogehogeは構造体です */ public: tagStructName(){}; void memberFunction(); } などとありました。構造体の継承?何それって状態なんですが 考え方としてはクラスと同じ考え方でいいんですか?
良い
おk すみませんでした
548 :
デフォルトの名無しさん :2006/03/05(日) 13:03:20
産みの親の発音を教えて
そんな無理に話題作らなくてもいいから
テンプレの[禿 Stroustrup]ってのみて 秀丸の人が開発者コミュニティでも作ったのかなと思ったじゃねーか
ちなみに他には ハーブサッター=髭 メイヤーズ先生=ふさふさ と言われている 覚えておくといいぞ
554 :
デフォルトの名無しさん :2006/03/05(日) 16:48:17
質問です。XP、VS8 です。 変数が静的か動的かを調べる方法はないでしょうか? 具体的には、以下のようなことがしたいと思ってます。 list<int *> List; // 静的な変数を追加 int a=0; List.push_back(&a); // 動的な変数を追加 int* b = new int(0); List.push_back(b); // 全開放 list<int *>::iterator itr; for (itr=List.begin(); itr!=List.end(); itr++) { if ( (*itr) が動的に確保された変数 ) delete (*itr); } List.clear(); よろしくお願いします。
標準にはないな。
556 :
554 :2006/03/05(日) 17:15:41
設計を見直すしかないでしょうか・・・。 ありがとうございました。
そんなことしたくなる状況がわからん
>>554 動的な変数へのポインタのみを保持したコンテナをListとは別に作って
deleteはそちらのコンテナのイテレータを介して行うとか?
すみませんが少々お力添えをいただけますでしょうか。 コンパイラはVC8で, cl code.cppとコンパイルしています。 現在とある画像ファイル形式(パレット方式、\0をランレングス圧縮)を BMPに変換するコードを書いているのですが、 byte *cdata = new byte[ihead.length]; ifs.read(reinterpret_cast<char*>(cdata),ihead.length); if(!ifs){ cout << "file read failed" << endl; return 0; } string data = Decode(cdata,ihead); // \0をデコード delete[] cdata; この流れで ihead.length==655 にもかかわらず、 ifs.tellp() で読み込みバイト数を調べると、 7000 バイトも読み込んでいるようなのです。 Decode 内で cdata を全て表示させて、ファイルと比較してみたところ、 読み込み位置が 639 バイト目から突然 4000 バイト以上後方にジャンプしていました。 seekg したわけでもないのに read 中にファイル読み込み位置がずれることはあるんでしょうか。
>>554 operator new / deleteのオーバーライドで
ヒープオブジェクトの一覧を作っちゃうとか。
まあ、そこまでするのもあれだけど。
>>554 おとなしいところで、フラグを使うとか。
typedef pair<bool/* dynamic? */, int *> flag_ptr;
list<flag_ptr> List;
// 静的な変数を追加
int a=0;
List.push_back(flag_ptr(false, &a));
// 動的な変数を追加
int* b = new int(0);
List.push_back(flag_ptr(true, b));
// 全開放
list<flag_ptr>::iterator itr;
for (itr=List.begin(); itr!=List.end(); itr++) {
if (itr->first)
delete itr->second;
}
List.clear();
>>560 Effective C++だとそれだったな。
>>559 画像ファイル等等の話は余計じゃね?
564 :
559 :2006/03/05(日) 17:50:03
>>562 お早い返信ありがとうございます。
std::ios::binaryを指定したら、嘘のように成功しました。
お騒がせしました。
>>563 お恥ずかしながら、原因がまったく見当がつかなかったので……。
今思うと処理の内容は関係なかったですね。申し訳ありませんでした。
VisualStudio.NET ATL/WTL で開発しています。 バイナリから、JScriptの関数を呼びだすコードを書いております。 関数の呼び出しはできるのですが、JScript上の関数に引数を渡さなければいけない 場合に、どのように渡せばよいかわからないことがあります。 現在はまっているのは、JscriptのArray型です。 SAFEARRAY で CComVariantに渡してみましたが、 JScript上の関数内で、Arrayのlengthプロパティを使用できませんと 言われてしまいます。 この場合は、どのように渡せばよいのでしょうか? また、 参考になるようなページはありませんでしょうか? JScriptの関数呼び出しには、Invokeを使用しています。 よろしくおねがいします。
567 :
565 :2006/03/05(日) 19:30:23
すみません。 ATL/WTL スレに書いてきます。
568 :
デフォルトの名無しさん :2006/03/05(日) 21:37:45
ある class A があります この class を引数で受け取る関数があります void func( const set< A >& va ); この関数の中で、それぞれのAのインスタンス用に一時的な記録領域を設けたいんです。 引数にはconstで受け取りますから、class定義に含めることは出来ません。 解法として2つ考えたんですが、どっちもベストな方法には思えません。 皆さんならどう実装しますか? 1. mapを使う map< A*, A_Temp > tempMap; A_Temp at = *temp.find( &*va.begin() ).first; 2. class A に作業領域を含める class A{ public: void* pTemp; ...}; A_Temp at = (A_Temp*)va.begin()->pTemp;
>>568 func内で完結するデータなら1。
Aのインスタンスのある限り必要なデータなら2。
1だとしたらポインタでなくconst_iteratorをキーにすればよいと思う。
>Aのインスタンス用に一時的な記録領域 この意味がわからないんだが。具体的な例きぼん。
>>569 例えば、funcの中で、AとTempAの情報を受け取るfunc1を呼ぶとすると
func1の定義は以下のようになってしまい、なんだか複雑さが伝播してしまいます。
元々の設計が悪いのでしょうか?
void func1( const set< A >& va, map< A*, A_Temp >& tempMap );
>>570 何でもいいんですが、例えばプリンタの情報を収めるクラスがあるとします。
class Printer;
void main(){
Printer p;
// ユーザがPrinterオブジェクトに対しいろいろな操作を行う
p.set_XXX();
p.method_XXX();
// ・Printerの集合を受け取るfunc関数があるが
// この関数は、Printerに対し直接的な変更を加える訳ではないので
// const属性で受け取りたい
// ・内部では、ソートなど集合に対し操作を行うので
// 個々のインスタンスに関連付けされた領域が必要
set< Printer* > setp;
setp.insert( &p );
func( setp );
};
class PrinterWithSomeInfo{ public: PrinterWithSomeInfo(const Printer *printer) : printer_(printer) {} const Printer *getPrinter() const {return printer_;} private: const Printer *printer_; [その他必要ないろいろ] }; のsetを渡すとか。
void func(const set<A>& va); じゃなくて void func(set<const A>& va); にしたいって話?
>>572 それでいってみます。
ありがとうございます。
>>573 そうですね、
その他いろいろ間違ってます。
こういう適当な性格なんで、PGには向いてないです。
ソートしたいだけなら、それでおkな気がするね。
すみません。 試す前に聞いておきたいのですが、 テンプレートな、可変引数の関数というのは作れるのでしょうか? template <typename T> void func(T t, ...) {
>>576 それ、そのまんまでなにも問題はありませんが、なにか?
> 試す前に聞いておきたいのですが、 シネヨ
579 :
576 :2006/03/06(月) 00:04:40
>>577 作れるのですか。
ありがとうございます。早速試します。
(゚д゚)
(゚ д ゚)
ヘッダファイルで template<typename T> class A { void func(const T& ); } のように宣言したメソッドfuncをcppファイルで実装しようとするとうまくいかないんだけど、 そもそもできないものだったりします? template<T> void A<T>::func(const T& ){} だと、外部からコールしたときに 外部参照が未解決だとコンパイラに怒られてしまう。
他でも使うtemplateは全部ヘッダに書きなされ
>>582 標準仕様に、完璧に準拠したコンパイラならいける。
つまり、exportキーワードを使えばいい。
まあ、VCもGCCもサポートしていないわけだが。
>>585 テンプレート引数に渡す型が予め分かってるなら
明示的実体化という手もある
例えばintとdoubleで実体化するのであればcppファイルに
template class A <int>;
template class A <double>;
と書いておく
自分のゲームプログラムなんですが templateの使いすぎなのか デバッグビルドだと重くて、まったく試運転出来ないのですが そういうものですか? VisualC++7.1 リリースビルドで30FPSなものが、デバッグだと0FPSになります。
templateは関係ないよ、コンパイル時に全部展開されるから。
>>588 それを期待して inline 重ねまくったコードが
デバッグビルドでボロボロになるんだよ。
templateってデバッグビルドだと実行時解釈される事あるの?
>>590 それはないが589はinline展開について言ってるのでは?
なんで急にinline展開について言うの?
>>582 ヘッダファイルからcppファイルをインクルードしれ。
最初は違和感あるかもしれんけど、
template の時だけはこのスタイルがベスト。
きんもーっ
インライン関数みたいな感覚でヘッダに実装したほうが自然じゃね?
漏れもヘッダに入れるのが普通だと思う
俺もそう思う コンパイルして使うものは *.cpp コンパイルしないで使うものは *.hpp ってしてる
同じく。 別ファイルに分けたいときは 拡張子はcppじゃなくhppにしてる。
599 :
デフォルトの名無しさん :2006/03/06(月) 11:54:33
int func() { while(1) { /* 処理 */ if (条件) return 1; } return 0; } この条件で抜けるとネストが深くなるとか、そういった問題は起きないのでしょうか? break;で抜けるのしか見たことがないので不安です。
>>599 無問題
ネストが深くなるってどんな意味で使ってる?
601 :
599 :2006/03/06(月) 12:05:46
>>600 ありがとうございます。
>ネストが深くなるってどんな意味で使ってる?
繰り返しの中に繰り返しとかです。
もし return 1; で抜けていなければ、何回もこの関数が呼ばれてこの条件で抜ける度に
while(1){
while(1){
while(1){
/*中略*/
}
}
}
みたいな感じに処理されてるのかと思ったんです。
昔HSPを使っていたときに、
repeat〜loopからちゃんと抜けずにgotoを使うとそういった現象に見舞われましたもので。
[1] もし return 1; で抜けていなければ、 [2] 何回もこの関数が呼ばれてこの条件で抜ける度に 抜けていなければ、抜けるたびに……? ネストが深くなる、というより、スタックの処理が適切になされるかという意味かな。
>>601 「関数が呼ばれるたびに、whileが増えていく」ってことか?
ぶっちゃけありえない。
>>601 悪いことは言わないから、HSPのことは、きれいさっぱり忘れろ。
ようは、whileブロックの「終了処理(とでも言うべき何か)」がbreakによって行われるように錯覚していて。 returnでいきなり関数を抜けると、whileブロックの「終了処理」が行われずに関数処理が終わってしまう。 だから、次に同じブロックに処理が来たときに、前回の中途半端な状態が残っていて、おかしな動作に なってしまうんじゃないか、てことだろ? そういうアセンブラチックなことをしなくてすむのが高級言語なんだよ。 HSPはほんとうに低級なんですね。
deleteにNULLを渡しても大丈夫と言いますが、 DirectXのユーティリティなどで、 #define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } と定義されているのは、何故なのでしょうか
>>606 そのdefineと、NULLをdeleteするのとは、違うだろ〜。よく見なされ。
>>607 いやいや、deleteにNULL渡してもOKなら
このマクロもifチェックいらないはずなのに何故、という話です
冗長だからだろ 問題ないのと、コストがかからないのとは違う
むしろif書いた方が冗長な気がするが
SAFE_RELEASEと一貫性を保つため?
DirectXのソースコードは超絶ウンコだから気をつけろ そのifは必要ないし、inline+templateでも書けるところを わざわざマクロを多用してるし、newが例外投げることすら 知らないし、C++初心者が書いてるようなレベルだ
2重にdeleteしちゃったりしても、不具合でないようにしてるのかな
単純に if(NULL) と delete NULL じゃ、delete NULL のほうがコストが 高いからじゃねーの?
ひょっとしたらNULLをdeleteしたら落ちるんじゃないかとDXUTを書いた人たちが不安に思っていたにいっぴょ。
NULLを渡されると落ちるような蛸なDebug用deleteを使われることを恐れてNULLチェックしているに一瓢。
つか、昔の VC++ だと delete に NULL 渡すと落ちた気がする。
昔のVCのnewはメモリ不足の例外は投げなかったな。
VC6 までそうだったね。 自分で例外投げるようにハンドラすげ替えたりして。
まあvc6はC++じゃないから仕方ない罠
VC6が糞なのかそれにさっさと取って代わらないドトネトが糞なのか
>>606 new の回数と delete の回数が一致してないと気持ち悪い、とか
new していないものを delete するのは気持ち悪い、とか。
ところでさぁ、さっき思いついたんだけど、 C++のこと、これからは「しーぷらら」って呼ばない?
>>622 newしてないものをdeleteしちゃまずいぢゃないか!
そういえば、しーぷらぷら君ってどこ行ったの?
しーぷらぷら君ってだれ?
628 :
デフォルトの名無しさん :2006/03/06(月) 21:54:46
じゃぁ、「しぃぷらら」
EYECOMに載ってたやつ。
じゃ「ディズニーシー」
631 :
デフォルトの名無しさん :2006/03/06(月) 22:02:37
「しーたすたす」でええやん
時代は強い言語を求めているッ!! C卐卐 シーダブルハーケンクロイツだッ!!
633 :
デフォルトの名無しさん :2006/03/06(月) 22:07:43
「しぃぷららん」にしたほうが可愛くね?
634 :
デフォルトの名無しさん :2006/03/06(月) 22:08:20
XとかZでよくね?
635 :
デフォルトの名無しさん :2006/03/06(月) 22:17:27
「しぃぱふぱふ」
636 :
デフォルトの名無しさん :2006/03/06(月) 22:19:20
「シー禿」
637 :
デフォルトの名無しさん :2006/03/06(月) 22:20:48
「禿C」
638 :
デフォルトの名無しさん :2006/03/06(月) 22:21:00
しーぱげぱげ
639 :
デフォルトの名無しさん :2006/03/06(月) 22:22:39
しぃツルッパゲ
つるピカハゲしぃくん
しぃツルりん
しーダメダメ
今禿って言った香具師ちょっと来い(`_ゝ´)
しーダメダメ
メイドさんCC
ちょwおまいらwwwww
647 :
デフォルトの名無しさん :2006/03/06(月) 22:29:10
C C++ C# C## C####
>しーダメダメ C言語できないやつに取れる
>>648 test.cxx←テスト点シーダメダメって読んでた
しーだめだめ相談室 びじゅある しーだめだめ
しーぽんぽん
>612 答え:DirectXはC言語でも扱えるように作られている
まぁ「DirectXのソースコード」って表現が既に電波だな
ヘッダはソースコードではありませんか?
ありませんねぇ
>>656 そんな言い切れるほどの根拠はないだろ。
ちなみにプリプロセッサディレクティブ #include の機能は
"Source file inclusion" と言われる。
DirectXのヘッダーについて言うなら、>652はわりと正しい意見だと思う。 windows.hがいつまでたっても古臭いマクロとか#define定数とかに頼ってるのも、そう考えれば納得がいくな。
Cとの互換性とかいい加減X8で切っちゃえば良かったのに。 いくらなんでももうCでDirectXプログラミングとか無いと思うんだが
同感。 今時WindowプログラミングでC使うならbetter CとしてのC++を使えばいいし(一部特殊用途除く)。 DirectXをCで使う必然性って何よ?
C丼
SAFE_DELETE() の勘違いが C と関係あるわけないだろ。
SAFE_DELETEはDXUTじゃなかったっけか?
最適化のパフォーマンスは C と C++ どっちが上げやすいのか?
665 :
デフォルトの名無しさん :2006/03/07(火) 07:47:20
たすたすと呼称 『Cで書いてんの?』 『いや たすたす。』
C + _ +)
Cくさかんむり
668 :
デフォルトの名無しさん :2006/03/07(火) 09:08:16
expectedの解説と使い方?を教えてください。
explicitではなくて?
Cチョメチョメ
Cpp == Cpunipuniヾ(o゚ω゚o)ノ゙
>>613 が正解。
だからdelete (p); (p) = NULL;だけでもよいが、不安になる人がいるのでifを付けている。
かえって危ない。 #define SAFE_DELETE(p) do { delete (p); (p)=NULL; } while (0) と書き換えれ。
675 :
デフォルトの名無しさん :2006/03/07(火) 15:49:42
クラス化や operator という正攻法をさしおいてトリッキーなマクロ置換に走る奴のコードが 自分には回ってきて欲しくないんだが・・・
今からCしか使えないコンパイラに移ることも無いだろうし。 template<typename T> void safe_delete(T*& p) { delete p; p=0; }
std::fstreamから1bitずつ読み込みたいんですがどうしたらいいですか?
>>676 throw() もよろしく
ついでにsafe_delete_arrayとsafe_deleterとsafe_array_deleterも
>>676 template<typename T>
void safe_delete(T*& p)
{
typedef refuse_incomplete[sizeof(T)];
delete p;
p=0;
}
680 :
679 :2006/03/07(火) 17:23:21
間違えた…… template<typename T> void safe_delete(T*& p) { typedef char refuse_incomplete[sizeof(T)]; delete p; p=0; }
>>679 template<typename T>
void safe_delete(T*& p)
{
checked_delete(p);
p = 0;
}
ってこと?
こちらでよろしいでしょうか?
フレーム処理でちょっとてこずってます。
さまざまなサイトを参考にして、
メッセージループでフレーム制御をやってるのですが、
どうもうまく行きません。なぜかキーボードのキーを叩くと
アニメーションが停まってしまいます。
半日くらいgoogleほっつき回ったのですが、原因はついに分からず。
どなたか知恵を貸していただけないでしょうか?
一応ソースコードをアップロードしておきます。
環境はWinXP、VS.NET theSpoke Premiumです。
ttp://gamdev.org/up/img/4892.zip
せっかくtheSpokeで買ったならtheSpoke.netで聞けよ・・・
684 :
679 :2006/03/07(火) 17:42:56
>>677 バイト単位で読み込んでからビットに刻む
686 :
デフォルトの名無しさん :2006/03/07(火) 19:49:28
質問:VS2003上で動作しているか調べる方法はありますか? わたくしはVisualStudio2003 VC++を使っております。 DebugかReleaseかはDebugを使っています。 現在VS上でプログラムを実行してるのか、できたEXEを直接動かしてるのか プログラムで判断することはできますか???? GetCurrentDirectory()を使ってカレントフォルダを表示させるプログラムを作りました。 VS2003上でF5を押すときとは、カレントフォルダの最後に\Debugがつかないで 直接EXEを実行させるとそれがつくという違いがあるのはわかったのですが、 別な方法で正しくVS上で動作させているかプログラムで判別する方法はある のでしょうか?
>>686 日本語でOK
後、1も読めない文盲は氏ね
688 :
デフォルトの名無しさん :2006/03/07(火) 20:40:44
はじめましてこんにちは。 質問があります。C++でCGIのプログラムは終わって、テスト鯖でのコンパイル→実行→テストも終わったのですが、いざ、これを無料鯖に載せて公開しようとしたところ・・・SSHの使えない鯖で、コンパイルできません。 鯖環境がどういうものか書いていない鯖なもので、ウィンドウズかBSD系でのコンパイル済みファイルをアップしても動作しない為、鯖は別環境と推定されます・・・。 っが、なんとか簡単に鯖でコンパイルすることは可能でしょうか? 他のプログラムを使う事もできるのですが、個人的に、C/C++が好きということもあり、できる限り上記の方法での解決をしたいと思っております。 ちなみに、以前、どこかでそのようなスクリプトを見た事があるのですが、どうも思い出せません。 CGIファイルに・・・スクリプトで・・・G++をECHOで呼び込んで・・・・ってのはわかってるのですが・・。自分の知識の範囲外です。 お手数とは思いますがよろしくお願いします。 (ウェブプログラミングはPerl、PHP、JSP等の方が良いとわかっていても、C/C++やJavaなどのオブジェクト指向系(あくまで系)の方がいいっすb
>>688 #/bin/sh
echo Content-type: text/plain
echo
make hoge
691 :
デフォルトの名無しさん :2006/03/07(火) 21:02:09
>>688 さっそく回答ありがとうございます!
これです!昔見たやつです!!
早速、試させていただきます。ありがとうございましたb
オブジェクト指向系の言語が使いたくて スクリプト言語を使いたいなら、 Ruby や Python を鯖でコンパイルするといいよ。 容量圧迫するけど。
693 :
デフォルトの名無しさん :2006/03/07(火) 21:18:37
クラスがメンバー変数として配列を持っていた場合、どうやって初期化すれば良いのでしょうか? class Class { public: int array[10]; } Class:: Class () : /* ここでarrayを初期化したい */ { } ;
694 :
682 :2006/03/07(火) 21:18:38
>>683 じゃ、そちらで聞きなおしてきます。失礼しました。
>>693 コンストラクタ内で初期化代入するしか。
Class::Class() {
static const int arrayInits[] = {0, 1, 2, 3, 4,};
std::copy(arrayInits, arrayInits + sizeof(arrayInits) / sizeof(*arrayInits), array);
}
>>686 カレントフォルダは好きに変えられる。
たとえばショートカットを作れば、ショートカットのプロパティで設定できる。
もしもEXEの存在するフォルダを知りたいのであれば、
EXEへのパスを取得し、それを加工してEXEファイルのあるフォルダへのパスを取り出すようにすべき。
(書き終わってからスレ違いだと気づく_| ̄|○)
>>686 実行時に渡すパラメータを決めるオプションがあるから、
自分で何かパラメータ渡すように設定しておいて、
そのパラメータがあるかどうかで判定すれば良さげ。
直接動かす場合でもそのパラメータ渡せば誤認させられるけど、
どうせ Debug バージョンでしか有効じゃない処理だろうから、
そのくらいいい加減でもいいっしょ。
以上略
701 :
デフォルトの名無しさん :2006/03/08(水) 03:57:45
テンプレートを使ったクラスや関数をライブラリ化しようと思っています。 テンプレートクラスは下記のような記述で明示的なインスタンス化ができたのですが、 template class Hoge<Moge>; テンプレート関数の場合は、明示的なインスタンス化はできないのでしょうか? 環境は、VS2005です。
どういうとき必要なのかは知らんが、 似たようにしてできない? あるいは template の後に <> を書くか。
>>701 template<class T>
void func(const T &) {
...
}
void func<int>(const int &);
たしか、こんなんでいけたと思う。
>>701 template<class T>
void func(const T &) {
...
}
template void func (const int &);
typenameつかおうね
707 :
701 :2006/03/08(水) 06:08:49
>>702-706 レスありがとうございます。
参考にさせて頂いて、手探りでいじってた所、
↓これで、一応コンパイルは通りました。
template void func<int>(const int&);
typenameを使うべきところは見当たりませんがwww
template<class T>をtemplate<typename T>と書けということではないかと思う。
どっちでも同じじゃん。 まあ、俺は typename のが好きだけど。 template <typename> class T とかだと typename 使えないけどね。
>>711 テンプレート・テンプレート・パラメータ
>>711 テンプレート引数にテンプレートを渡すためのもの。
template<typename T>
class Foo {};
template<template<typename U> class T>
class Hoge
{
T<int> Bar;
};
Hoge<Foo> ahya;
Uは使わないから710のように省略できる。
「引数に渡す」ってのは、変な表現のような気がする 普通「引数」というと「実引数」のことじゃね?
715 :
デフォルトの名無しさん :2006/03/08(水) 10:18:01
>普通「引数」というと「実引数」のことじゃね? 実と仮のどちらかがデフォってことはない あくまで「不明」もしくは周りの文脈から推定するのみ
モダンは確か「テンプレート引数」っつってたと思う
>実と仮のどちらかがデフォってことはない >あくまで「不明」もしくは周りの文脈から推定するのみ 過去の経緯からそうなってしまった、ってのは理解ってるんだが…… 一つの文章の中で argument と parameter をどちらも「引数」と表現するのはやめてほしいなあ
「仮引数に渡す」という表現でもおかしいんじゃないか? 「テンプレートにテンプレートを(引数として)渡す」だろ。
719 :
デフォルトの名無しさん :2006/03/08(水) 14:05:01
確かに、送り側から受け側まで含んだ系全体を指すニュアンスで「引数」というケースはあるな
720 :
デフォルトの名無しさん :2006/03/08(水) 16:31:23
>>686 の父です
697,698さんどうも情報ありがとうです。
やりたいことは、関連してプログラムに使用したいファイルがあって
プログラムからみて相対パスで実行させようとして、
@プログラムはC:\AAA\PROGRAM1\debug\PROGRAM1.EXEで
A関連ファイルはC:\AAA\hogehoge\hogehoge.txt
のときに相対パスを使ってVS上かどうかで相対パスが
"..\hogehoge\hogehoge.txt"と"..\..\hogehoge\hogehoge.txt"
の2通りでてきてしまうのですが、なんとなくカレントフォルダを
現在実行しているプログラムの存在するフォルダに変更してしまえば
相対フォルダも同一になりそうな気がするので、たぶん問題解決です。
どうもありがとうございます。
boost::enable_shared_from_this クラステンプレートは面白いな。 何の変哲もないポインタから、shared_ptr が生成される仕組みは 単純だけど、目から鱗って感じ。
ソース読んだけど全然理解できん。
724 :
デフォルトの名無しさん :2006/03/09(木) 00:38:48
読んでみたけど・・・ どういった場面で使うのかわからん _internal_weak_thisがどこで初期化されてんのかよくわからん あと、const T を T const と書いてもいいことを知りますた。
>>724 Tがポインタだった場合に備えてじゃない?
とソースを読まずに言ってみる
おお!なるほど。 あと、boostの前スレにenable_shared_from_thisあったね。 でもそれ見てもわからんかったので寝ます。おやすみ。
デフォルトコンストラクタ A() とコンストラクタA(a, b, c) という2種類のコンストラクタを持つクラスを定義し、 それを継承したクラス class B : public A のデフォルトコンストラクタB(), B(a, b, c) があるとします。B(a, b, c)が呼ばれたら A(a, b, c) が呼ばれるようにできますか?明示的に B(a,b,c) の中で呼ぶしか無いでしょうか?
B(int a, int b, int c) : A(a, b, c) { // B(a, b, c)の処理... }
732 :
デフォルトの名無しさん :2006/03/09(木) 03:06:07
各種の operator にも名前空間というモノがあるんでしょうか?例えば namespace N { class A { 略 friend std::ostream& operator<<(std::ostream&, const A&); 略 };//class A }//namespace N のように宣言した場合、この operator<< は正確には N::operator<< ということになるのでしょうか。するとその実際処理を定義する場合にも N::operator<< として定義するべきなのでしょうか? そもそも std::cout << "aiueo\n"; の時の operator<< は ::operator<< なのか std::operator<< なのか・・・ ちょっと混乱しています。
>>732 もちろん、演算子も名前空間の中に入る。
こういう風に書くとわかりやすいかも。
やっていることは同じコード。
std::cout << "hello,world" ;
std::operator << (std::cout, "hello,world") ;
まあ、実際に使うときは、ADL、Koening Lookupなどと呼ばれている仕組みにより、
名前空間を明示しなくても呼び出せるんだけど。
734 :
デフォルトの名無しさん :2006/03/09(木) 03:27:13
>>733 ありがとうございます。
std::cout << "aiueo\n"; の時の << は
std::operator<< だったんですね。
その点は疑問が氷解しました。
>>722 の friend にした operator<< は、N::operator<< なのでしょうか?
というのは、class A のインスタンス a を std::cout << a; のように
ストリームに流すときの << もやはり std::operator<< なので、
friend 指定の時に
namespace N {
class A {
略
friend std::ostream& std::operator<<(std::ostream&, const A&);
略
};//class A
}//namespace N
のように operator<< の前に std:: を付けてみると、
std::operator<< should have been declared inside 'std'
とコンパイラに怒られます。そこで何も名前空間を指定せずに
>>722 のように宣言したはいいものの、その定義では
どう書くべきなのか分かりません。 N::operator<< なのでしょうか?
735 :
デフォルトの名無しさん :2006/03/09(木) 03:27:46
736 :
732=734 :2006/03/09(木) 03:39:20
>>732 で friend 指定した operator<< は
フルネームでは N::operator<< ですね。
*.cpp ファイルで定義する際にも N::operator<< で行けました。
今まで N::operator<< はクラス定義のヘッダファイル中に
直接書いていたので、いざ定義と宣言を分離しようとすると
困ってしまっていました。
Koenig Lookupにも限界があり、std::ostream_iteratorに 自前のクラスやstd::pairなんかを食わせると、標準に正しく準拠した コンパイラではエラーになる。 operator<< を std名前空間に入れないとだめだからだが、標準C++ はstd名前空間をいじってはいけない事になっている。
738 :
732=734 :2006/03/09(木) 04:22:44
>>737 このあたりは Visual C++ と g++ で挙動が違い、
悩むこともしばしばでした。さらに同じ g++ でも
バージョンによって挙動が違うこともあるので余計に。
>>737 自前のクラスなら operator をクラスと同じ名前空間で宣言すれば大丈夫。
std::pair はやっぱり無理。
>>738 friend のルールは複雑でそういう問題も発生するし、
元々がなるべく使わないで済ませたほうがいいものなんで
public な入出力メンバ関数を作っておいて、 operator では
それらを呼び出すだけにするのがいいと思う。
ちなみに gcc だと 3.4, 4.0, 4.1 と毎度 friend 周りで挙動の変更が入っている。
>>734 ちなみにstd::cout << "aiueo\n";の<<は
std::basic_ostream::operator <<のメンバ。
基本型とマニピュレータに対するoperator <<はstd::basic_ostreamのメンバ。
えー、標準C++だとfinallyが無い(gccには__finallyも無い)ので 普通はスタック上のオブジェクトのデストラクタで代用する。 これは、メモリ/ファイル/コネクション等なら普通に使えるし 大抵はいろいろな処理をまとめてclassとして扱うので抵抗は無いのだけれど これがロックとかだと、若干使いにくい気がする。 というのは、まず、ロックのためにclassを定義するというのもなんか嫌だし unlockするタイミングを確定させるためにわざわざブロックを作って その先頭にロックオブジェクトの宣言だけが現れる(操作がソース上に現れない) という形になって、美しくない(気がする)。 で、operator bool()が必ずfalseを返すこんなclassと#defineマクロを使って Synchronized(x) { } を擬似的に作ってみたのだけれど、まずいところあるかな? class synchronizer { LockObject& lock; explicit synchronizer(LockObject& lock) : lock(lock) { lock.lock(); } ~synchronizer() { lock.unlock(); } operator bool() const { return false; } }; #define Synchronized(x) if (synchronizer ___locker = synchronizer(x)) ; else
>>742 JLib2 (
http://www.codeproject.com/library/jlib.asp ) に、
ほとんど同じコードがあったな。こっちは operator bool が常に true を返してたけど。
ただ、注意書きのところに、
// used to be "#define synchronized(x) if ( jlib::lang::Lock l_o__c_k(x) )",
// up to the C++ standard, this seems to be incorrect, it can only be
// accepted by MSVC. See C++ Language Specification, A5.
とか書いてあったから、いいかどうかは微妙なところ。
>>742 結局ロックのためにブロック作ってるのは変わらないし
ロックオブジェクトを先頭に置くのが美しくない?とかってのも
単に見慣れてるかどうかでは?
{
ScopedLock<LockObject> lock;
...
}
みたいなので十分分かるとは思うな
言語が synchronized構文とかサポートしてるのならともかく
オレ流マクロで構文モドキを作るのは余計説明しにくいような
あー、やっぱり、俺が考えつく程度のことは 当然誰か他の人も思いついてるんだよな。 どこが引っかかるかは、よく読んでから考えてみる。 とりあえず、ifの()内の変数宣言は、大昔のコンパイラは対応してないし。
>>729 おー、template特殊化でコンパイル時に型判断してるんですね。
template恐るべしですな。
VC7.1で、意味はありませんが、こんなコードがありまして boost::bind(std::less<int>(), _1, 2)(x) ; さらにこうすると、コンパイルできません。 boost::not1( boost::bind(std::less<int>(), _1, 2) )(x) ; これならOKのようです。 boost::bind( boost:not2(std::less<int>()), _1, 2 )(x) ; これなら通るのですが。 std::not1( std::bind2nd(std::less<int>(), 2) )(x) ;
748 :
747 :2006/03/09(木) 16:19:32
boostスレに行くべきだったかな……。
#include "boost/lambda/lambda.hpp" #include "boost/lambda/bind.hpp" (!bind( std::less<int>(), boost::lambda::_1, 2))(x)
750 :
747 :2006/03/10(金) 00:54:56
>>749 おお、boost::lambdaすごい。
これは面白い。
STLのbind1sとかbind2ndとか、キモすぎで、
今まで使おうとは思わなかったんですよ。
751 :
デフォルトの名無しさん :2006/03/10(金) 06:58:49
演算子のオーバーロードはインライン的に高速ですか? これも、クラス宣言に書いたり、inlineとかつけるとか?
気になる「的」の用法だな
753 :
デフォルトの名無しさん :2006/03/10(金) 08:28:33
代入演算子のオーバーロードをフレンド演算子関数で実装できないのは何故ですか?
>>751 普通の関数と全く同じように考えればよい。
インラインに書けばインライン展開されるだろうし、そうでなければ関数呼び出しになるだろうし。
755 :
デフォルトの名無しさん :2006/03/10(金) 08:43:45
>>753 する必要がないから。あれメンバ関数よ?
加算演算子とかをfriendにするのは、
メンバ関数じゃないけど中身直接いじれると便利だから。
757 :
デフォルトの名無しさん :2006/03/10(金) 23:11:09
>>753 その問いに対する答えはただ1つ: 規格で禁止されているから
「なぜ禁止しているのか」なら、これは想像だが
struct X { }; つまり operator = が宣言されていないクラスに対して、
const X& X::operator = (const X&); が翻訳環境によって追加され、
そこへ随伴宣言があると例えば vtable の生成則がおかしくなったりしそうだろ
左辺に組み込み型を持ってこられると困るからでは? もしフレンド関数でオーバーロードを許すなら、他のoperatorとシンタックスを合わせないといけないだろうし
D&Eにはoperator =が非メンバで定義されると、 場所によってコピーの方法が変わると言うまずい状況になるから メンバとしてしか定義できないようにしたと書いてある。 ただしfriendまでは言及されていないが。 struct Hoge {/* 〜 */}; Hoge x, y; x = y; //デフォルトのコピー Hoge& operator =(Hoge&, const Hoge&) {/* 〜 */} Hoge z; z = x; //さっきのoperator =()
760 :
デフォルトの名無しさん :2006/03/11(土) 01:28:37
これもC++の歪みってやつか
762 :
デフォルトの名無しさん :2006/03/11(土) 19:39:46
コンストラクタAで他のオブジェクトBをnewしているとします。 しかし、そこでメモリが足りなかったとします。 Aがnewで作成されている場合にポインタにNULLを返したいのですが、どうすればいいのでしょうか? #include <stdio.h> class B{}; class A { public: A() { B *m_pB = new B; if (m_pB == NULL) { //ここでA()にNULLを返させたい。 } } private: m_pB; }; void main() { A *pA = new A; if (pA == NULL) printf("NO MEMORY\n"); }
>>762 コンストラクタじゃ無理。newをオーバーロード汁
764 :
デフォルトの名無しさん :2006/03/11(土) 19:55:06
すみません、教えてください class を使ってるということは C++ なんだと思うんですけど iostream じゃなくて stdio を使う意味を教えてください。
766 :
デフォルトの名無しさん :2006/03/11(土) 20:10:29
scanf を愛しているから
>>764 iostreamはでかいんだよ。
それを静的リンクするとフロッピーディスクに入らなくなる。
動的リンクするとDLLが無いとサポートに電話がかかってくるんだよ。
>>762 標準に準拠したコンパイラでは通常newはNULLを返さない。例外を投げてくる。
例外を投げないようにするのにはnew(nothrow) B;などと書く。
挙げている例の場合、普通は例外を使うか、正常に構築出来なかった事をメンバ関数で伝えるか、何らかの生成用関数を挟む事などが考えられる。
769 :
デフォルトの名無しさん :2006/03/11(土) 20:33:57
ふと疑問 newがメモリ不足で失敗した場合に、printf()とかが まともに動く保障はあるの??
770 :
デフォルトの名無しさん :2006/03/11(土) 20:40:11
そろそろprintfの呪縛から解放されないか? printfは、諸悪の根源。
771 :
デフォルトの名無しさん :2006/03/11(土) 20:56:07
>>769 聞いたことねえな
printf が内部で new を使うはずがなさそうだし、まして仕様でなどありえない
仮に malloc を使っていても new と同じ系統のサブプールを使う可能性はあっても保証はできっこない
operator new がユーザ定義される場合があるのだから
>>770 じゃあ、boost::formatの時代だな。
773 :
デフォルトの名無しさん :2006/03/11(土) 22:53:05
ポインタを返す関数の作り方がわかりません。 ソースはこんな感じです。 typedef struct int a; int b; } WORK; WORK* クラス名::GetWork() { } ポインタの戻り値の設定ってこれでもおかしくないですよね。
もう春休みなのか?
>>773 こんなことやって悩んでいる予感。
WORK* クラス名::GetWork()
{
WORK w;
return &w;
}
776 :
デフォルトの名無しさん :2006/03/11(土) 23:21:38
違います。クラス内のパブリック変数のポインタを返してます
777 :
デフォルトの名無しさん :2006/03/11(土) 23:23:43
error: 2: unexpected type identifier `int'.
class hoge{ WORK w; WORK& get_w(){ return w;} }; こうじゃダメなんか?
779 :
デフォルトの名無しさん :2006/03/11(土) 23:25:22
class hoge{ WORK oma_www; WORK& cho_ww(){ return oma_www;} };
公開メンバ変数ってだけでもあれだが、それを指すポインタを返すメンバ関数って、 直接ポインタとるんじゃだめなのか?
782 :
デフォルトの名無しさん :2006/03/11(土) 23:44:59
構造体の宣言をクラスの外に出したらエラーがなくなりました。 なんででしょうか?
そういうことは先言えよ エラーメッセージ100回読んどけ
class C { struct S {...}; S* func(); }; C::S* C::func(){} C::が抜けてると見た。
なるほど・・内部クラスを使っていたのか
787 :
デフォルトの名無しさん :2006/03/12(日) 02:01:07
785さん、ありがとうございました。 ちなみに内部構造体を使ってました。
788 :
デフォルトの名無しさん :2006/03/12(日) 02:02:21
関数の中に関数宣言したいんだけど。
789 :
デフォルトの名無しさん :2006/03/12(日) 02:08:06
>>788 関数の中で、クラスを定義できたりする。
int main()
{
>>788 void f() {
struct local {
static void g() { }
};
local::g();
}
int main() { struct hoge{ static func() {} } ; hoge::func() ; }
前方参照2題 (1)typedef を前方参照する裏技って無いですか? ----hoge,h class Hoge; class ZZ { Hoge<int> *hoge; }; ----hoge,cpp typedef HogeHoge Hoge ; まともにやるとコンパイル不可 (2)テンプレートクラスの前方参照は出来ない??
間違えた orz × Hoge<int> *hoge; ○ Hoge *hoge;
>>793 HogeHogeがこうだとすると、
template <typename T>
class HogeHoge
{
/* 〜 */
};
HogeHogeの前方宣言はこうなる。
template <typename T>
class HogeHoge;
そしてクラステンプレートをテンプレート引数の指定なしにtypedefすることはできない。
typedef HogeHoge<int> HHInt;のようなことはできるけど、
typedef HogeHoge Hoge;は今のC++ではできない。
つ マクロ
テンプレートのtypedefができないのはちと悲しいよね
次のような名前空間があるとします。 namespace abcdefg { int result1(); int result2(); int result3(); }; もしもプログラム中どこからも int result3(); を呼び出しても参照してもいないとします。 この時実行ファイルに int result3(); の部分は組み込まれるのでしょうか?
コンパイラ、リンカの実装しだい。
801 :
デフォルトの名無しさん :2006/03/12(日) 15:13:00
>>799 それは名前空間とかには全く関係ない。
result1() と result()3 が同じ名前空間で宣言されていることと
result3() のコードがリンクされるかどうかは全く無関係
「result3() の部分が組み込まれるか?」というのはリンク対象
になるか?ということだと思うが、そりゃ result3() の定義を
含むオブジェクトファイルをリンカに食わせればたとえ全く
呼び出されていなくても無駄にリンクされるし、
当該オブジェクトファイルを静的ライブラリ化していたとして、
result1() の定義と result3() の定義が同じオブジェクトであれば
一緒にリンクされる。リンカの扱う単位はオブジェクトファイル単位だから。
組み込むだろ。 関すコールは直接呼ぶだけじゃなく、関数ポインタを使って間接的に 呼び出すこともあるんだから、そこまで追跡するのは無理だべ。 コールバック関数を外部モジュールへ登録するなんて場合もあるわけだし。
803 :
デフォルトの名無しさん :2006/03/12(日) 15:14:03
でもどこからも呼び出されていないエントリポイントが あるときには警告してくれるリンカもある。
805 :
デフォルトの名無しさん :2006/03/12(日) 15:18:37
コンパイラ、リンカの気分次第
806 :
799 :2006/03/12(日) 15:19:07
皆さんていねいにありがとうございます。 異なるアプリケーションで使えそうな関数を独自のライブラリとし、 複数のアプリケーションでプロジェクトに追加できるような形に した場合、この独自ライブラリの規模が膨らむほど実行ファイルの サイズはデカくなっていくと考えていいんですね?
807 :
デフォルトの名無しさん :2006/03/12(日) 15:19:56
>>802 それって参照したことになるんじゃない?
result3の識別子を使わずに確実に関数ポインタ得るのは無理だろうし。
>>806 静的リンクしてたら基本的にそうなるだろうな。
ただ、コンパイラ、リンカの実装によってはそうならない可能性もあるし、
特定の実装をターゲットにすれば回避策もいくらかはあるだろう。
一般的には、同じオブジェクトファイルに含まれるもの(不使用の関数/変数等)は
全て実行ファイルにリンクされるが
リンカによっては、それらを判断してリンクするときに除外するものもある。
つまり
>>804 。
「一般的なリンカ」なら、
>>801-802 。
810 :
799 :2006/03/12(日) 15:24:16
>>809 Borland C++ Builder 6 ではどうでしょうか?
811 :
デフォルトの名無しさん :2006/03/12(日) 15:24:50
>>806 違う。
そりゃ、細かいこと言えばコンパイラ、リンカの実装次第としか
言いようがないので一般論でしか書けないけど。
静的ライブラリを作成するなら各関数ごとに異なるファイルに
定義を書くといい。100個のある関数を100個の *.cpp に書いて
コンパイルしてできた100個の *.o から libhoge.a を作って置けば、
リンクしなけりゃならない関数(を含むモジュール)だけ
リンカが取り出してリンクしてくれる。
もし100個ある関数を一つの hoge.cpp に書いてしまえば、
それをコンパイルしてできた hoge.o に100個の関数が
全部含まれているわけで、そのうち一つでもリンク対象に
なってるとリンカは hoge.o 丸ごとリンクする。
って、のがよくあるリンカの振る舞いだと思う。
813 :
デフォルトの名無しさん :2006/03/12(日) 15:41:52
アドレスとポインタの差なんて、ちゃんと勉強した奴なら誰でも知ってるよ。
アドレスとポインタの差なんて、ちゃんと勉強した奴なら誰でも知ってるよ。
アドレスとポインタの差なんて、ちゃんと勉強した奴なら誰でも知ってるよ。
アドレスとポインタの差なんて、ちゃんと勉強した奴なら誰でも知ってるよ。
アドレスとポインタの差なんて、ちゃんと勉強した奴なら誰でも知ってるよ。
アドレスとポインタの差なんて、ちゃんと勉強した奴なら誰でも知ってるよ。
アドレスとポインタの差なんて、ちゃんと勉強した奴なら誰でも知ってるよ。
アドレスとポインタの差なんて、ちゃんと勉強した奴なら誰でも知ってるよ。
http://pc8.2ch.net/test/read.cgi/prog/1140616676/
814 :
デフォルトの名無しさん :2006/03/12(日) 16:09:21
ポインタとアドレスってちゃうん? ポインタはアドレスを格納するための変数?
ポインタには型情報が付加されている。 あとは、メンバ関数ポインタとか変態じみたもの。
ポインタは抽象インターフェース、アドレスは具体的なもの。
ポインタでもまだ具体的な実装を意識させすぎてしまう、って事で イテレーターが生み出されたんだろうな。
int var[N]; があったとき添え字 k を var[k] のポインタと呼んでも 一般の意味では間違いじゃあないんだよね。
紛らわしから一般の意味で言う場合はボインチャンって呼ぼうぜ
820 :
デフォルトの名無しさん :2006/03/12(日) 17:18:48
>>814 ポインタにアドレスを代入できるが
アドレスにポインタは代入できない
あまり関係ないが、「ポインタ」という言葉は 1) (型を持った)アドレス値 2) アドレス値を保持する変数 の2通りの使い方がされる。 厳密には1)なのだが、2)の意味で使われることも多いし、 人によっても使い方が違ったりする。
>>821 なにを根拠にそんないいかげんな情報を書き込んでるの?
ランダムアクセスできるのがポインタ コンストなポインタがアドレス ポインタはPOD型のイテレーター ―― C++厨の解釈 ――
C++厨なんて呼び方始めて見た
825 :
デフォルトの名無しさん :2006/03/12(日) 17:38:11
じゃ、C厨++ か?
飛び火しててワロス
禿中
828 :
デフォルトの名無しさん :2006/03/12(日) 17:44:07
>>829 値とそれを保持する変数が同じ呼ばれ方をすることがあるのは整数型でも同じ。
ただ、あの流れで「ポインタ」と「アドレス」を混同しているのが気になった。
>>829 malloc が返してるのはポインタ.
それを int に評価すると,多くの場合,そのアドレスの値が得られる.
832 :
デフォルトの名無しさん :2006/03/12(日) 18:47:18
翔泳社の「標準講座 C++」では 「ポインタ(pointer)とは、メモリーアドレスを保持する変数のことです。」 って書いてあったよ
833 :
デフォルトの名無しさん :2006/03/12(日) 18:49:22
>>831 「それを int に評価すると,多くの場合,そのアドレスの値が得られる」
多くの場合、ってのがポイントだよな。
834 :
デフォルトの名無しさん :2006/03/12(日) 18:51:49
質問です。えーマルチです。 (書くスレ間違ったっぽい、はきだめC/C++にかいてしまった) 入力された日付(YYYYMMDD)が正しいかどうかチェックしたいのですが、 チェックする関数が見当たりません。 フォーマットが正しいかどうかなら自分でチェックすればできますが、 カレンダーにない日付もチェックしたいです。(2006/02/30はエラーみたいな) チェック方法をしっている方おられました教えてやってください。 環境はVCでSDKです。(MFCは使ってはダメ)
>>835 方法も何もそのままだろ。
YYYY、MM、DDに切り分けて、
MMが1以上12以下でなければエラー。
DDはMMから最大日数を割り出して、(2月はうるう年も考えて)
1 <= DD <= 最大日数でなければエラー。
んな感じでいいんじゃないの。
漏れはmktime()とlocaltime()を使うのがいいと思う。
841 :
504 :2006/03/12(日) 20:25:04
>>840 1970年〜2038年までしか扱えないっぽい・・。
作ってるアプリが2038年まで使われるとは思えないが、
boost::date_timeとやらか、自作でいこうと思います。
842 :
835 :2006/03/12(日) 20:25:53
↑漏れは835です。
SystemTmeToFileTimeとか? この答えはスレ違いだけど。
>>843 俺は詳しく知らないがタブンSystemTimeToFileTimeではないか?
あんまり細かいことを言うなや兄弟。
class sound{ }; class Dsound{ sound foo[2]; }; の様なクラスがあり、soundの読み込みはファイルを指定していました。 またDsoundは、2つの別々のファイルを指定するようになっていました。 このDsoundに1つのステレオ音声ファイルを読み込ませたいのですが、 よい方法はありませんでしょうか? Dsoundが自前でステレオファイルを読み込むようにすると sound2つを持っている意味がなくなるので、良い方法ではない気がするのですが。。
>>846 Dsound がステレオ音声ファイルを受け取って
sound の読み込むファイルに変換してから渡せばいいんじゃね?
C++ 関係ないな。
>>846 1chの音声を取り扱うクラスsoundと
Nchの音声を取り扱うクラスmulti_soundにして
class multi_sound {
std::vector<sound> snd;
};
soundでは1chのみの入出力をサポート、
multi_soundではNchまとめた入出力をサポート
と思ったが、イマイチだな。
入出力は別クラスにして、音声の実データへのアクセスはfunctorを使ったらどうだろう?
849 :
デフォルトの名無しさん :2006/03/13(月) 12:53:19
void f(std::string); //#1 void f(const std::string&); //#2 main() { f("TEST"); } ↑ g++: error vc7: error bc5: #1 Borland が ぼけ ってことでいいと思う? #2 もユーザ定義変換だと俺は思うが、 途中の厳密合致もカウントされるのかな
>>849 errorってなんだよ。何の問題もないぞ。
それを使いました。843、844たすかったよ。ありがとう。
852 :
デフォルトの名無しさん :2006/03/13(月) 15:25:56
>>850 警告じゃなくエラーね、make が止まるほう
$ g++ a.cpp
a.cpp: In function 'int main()':
a.cpp:8: error: call of overloaded 'f(const char [5])' is ambiguous
a.cpp:3: note: candidates are: void f(std::string)
a.cpp:4: note: void f(const std::string&)
問題ないって、Borland が正解ってこと?
854 :
853 :2006/03/13(月) 15:58:51
あ、void f(std::string&);じゃなくてvoid f(std::string)なのね。
855 :
デフォルトの名無しさん :2006/03/14(火) 07:01:24
newしたオブジェクトをdeleteしたのに、 タスクマネージャの該当アプリのメモリ使用量が減りません。 どうゆう事でしょうか?
>>855 それは、コンピュータを再起動する必要があります。
857 :
デフォルトの名無しさん :2006/03/14(火) 07:49:43
プログラムがメモリを確保するのとOSがメモリを確保するのは1対1で対応してるわけじゃないよ OSがある程度まとめて確保してプログラムの要求で小出しする感じ
deleteしたメモリを何時OSに返すのか(あるいは返さないのか)は ライブラリに一任されている。
860 :
デフォルトの名無しさん :2006/03/14(火) 09:53:26
じゃあ心配しないでいいんですね^^
861 :
デフォルトの名無しさん :2006/03/14(火) 11:09:36
>>860 なんでそうなる?
現にタスクマネージャから障害が報告されているんだろ?
そのアプリが意図のとおりに動かなくていいのなら心配する必要もなかろうが
現にタスクマネージャから障害が報告されているんだろ?
>861 流れ読めよ。
865 :
デフォルトの名無しさん :2006/03/14(火) 11:51:12
悪かったよ
866 :
デフォルトの名無しさん :2006/03/14(火) 11:54:24
僕のために喧嘩しないで><
867 :
デフォルトの名無しさん :2006/03/14(火) 11:58:36
タスクマネージャがなにを報告してくれるの?
finallyの標準化って話はないの? そこかしこでコンパイラ拡張しまくってるのに そんなにコストのかかる話なのかね。
>>870 キーワードの追加は大きいだろうな。
文法もいじることになりそうだし。
デストラクタがあるから必要性が薄いってのもあるだろう。
>デストラクタがあるから必要性が薄いってのもあるだろう。 これはないな
lambdaなんてやる暇があったら(ry
育毛に勤しめ。
exportの実装まだ〜?
876 :
デフォルトの名無しさん :2006/03/14(火) 13:47:08
878 :
デフォルトの名無しさん :2006/03/14(火) 14:13:10
879 :
デフォルトの名無しさん :2006/03/14(火) 14:13:36
グローバル変数int *pをプログラムの最初の方でp = new int [10]として その後に更に配列を増やしたい時はp = new int [5]とすれば pには15個の配列はできるのでしょうか?
880 :
デフォルトの名無しさん :2006/03/14(火) 14:15:21
できませんよ。結論のみいいましたが。
881 :
879 :2006/03/14(火) 14:20:12
もし他の方法でできるのでしたら教えて下さい。
882 :
879 :2006/03/14(火) 14:26:30
検索したら解決しました。
883 :
デフォルトの名無しさん :2006/03/14(火) 15:07:28
vectorかrealloc使ったんじゃないの?
>>869 その構文がもうちょっとまともなら嬉しいんだけどな。無理だろうとは思うけど。
変態言語のまともな構文など逆説的変態性として排除されてしかるべきであろう。
C++がますます、変態、何でもあり、規格に実装が何時までも追いつかない、 そんな言語として発展しつつあって、とてもうれしいです。
>>869 "C++ Programming with STL.Lambda(Boost.lambda)"でいいけどな。
889 :
デフォルトの名無しさん :2006/03/14(火) 22:26:43
こぴーこんすとらくた
ぴーこ
891 :
デフォルトの名無しさん :2006/03/14(火) 23:15:35
Microsoft Visual C++ 2005 Expressで
C++勉強しようと思い、ブックオフで買った独習C++をみながら
例題見ながら打ったら、いきなりエラーが出た。
で、
http://wisdom.sakura.ne.jp/みたら 、標準のヘッダ宣言は
<iostream.h>じゃなくて、<iostream>なんだね
あとusing namespaceとか。
ただ、VC++6.0だと<iostream.h>で動いたので混乱した。
いつ、標準化されたの?で最近のC#もいずれ標準化されんの?
標準化されたとき、過去の定義された物に拡張された禁止事項が
増えるならわかるけど、ヘッダの宣言みたいなソースそのものを全部
書き直す事になるのって、標準化っていうの?
まぁ、俺の買った独習C++は見ると10年前出版のものだったけど
標準化ってどこの誰がしてんの、教えて。
殴りに行くから
【積年の】旦那にしてる密かな仕返し【恨みじゃー】
http://human5.2ch.net/test/read.cgi/ms/1141694640/ 8 名前:可愛い奥様[] 投稿日:2006/03/07(火) 11:05:23 ID:8dtluKkp
夫の歯ブラシで洗面所の排水溝掃除。
洗面所をビショビショに汚した罰だ。
20 名前:可愛い奥様[age] 投稿日:2006/03/08(水) 00:40:17 ID:pRrk6A21
前に頭きた時あって
1度だけ歯ブラシで肛門カキカキしちゃった
22 名前:可愛い奥様[] 投稿日:2006/03/08(水) 01:27:12 ID:gU5mHc7J
よかった。どこのお宅も同じようなことしてて。
24 名前:可愛い奥様[] 投稿日:2006/03/08(水) 01:36:35 ID:SSSFsTqE
そうそう、ヘンなモノはダンナのお皿へ直行だよね。
41 名前:可愛い奥様[] 投稿日:2006/03/08(水) 11:55:18 ID:sjj+/60Q
見てるだけで気が晴れるな!
皆さん、頑張ってね!
42 名前:可愛い奥様[sage] 投稿日:2006/03/08(水) 20:33:51 ID:Ju2N1s7+
年金分割が楽しみじゃのう
63 名前:可愛い奥様[] 投稿日:2006/03/10(金) 08:55:20 ID:qLfJYpJR
家族で密かにはぶっている。
男性は肉体が汚く、精神が美しい傾向がある。(気に入らない相手に肉体的攻撃を加える⇒精神的攻撃も加える男は猛者)
女は肉体が美しく、精神が汚い傾向がある。(気に入らない相手に精神的攻撃を加える⇒肉体的攻撃も加える女は猛者)
女は隠れて悪事をする。気に入らない女子を便所でボコったり、便器舐めさせたり、男の友人を使ってレイプ、仲間外れにしたり。陰口、嫉妬。
女は対人関係において、この汚い性格を隠そうとするため、外面が非常によくなる。(猫かぶり)
男性諸君は外面に騙されないように気を付けて下さい。
893 :
デフォルトの名無しさん :2006/03/14(火) 23:17:47
標準化しているのは ISO あと、C# は関係ない。 禿は殴らないであげてね。
The C++ standard was published 1998-09-01 by ISO ITTF as ISO/IEC 14882:1998. ちなみに、94年に作業原案(WD)が委員会原案(CD)になっている
いったんJSに吸収されたCの血統が帰ってきた。見たいな感じだね。 クロージャは便利そうだから結構ほしかった。 Lambdaとfunctionまたは、closureを予約語にしてしまったほうが綺麗なきがする。 色付きエディタで映えるし。 安易かな・・・。
禿はあんまし予約後を増やしたくない、みたいな話をしてたなー。 たとえば、今までclosureという変数名を使ってた奴らのことも考えてやれよ、って。
898 :
896 :2006/03/14(火) 23:32:43
書いてる間にすれ伸びてら。
おっとさらに伸びてる。
>>897 俺はそんな変数名使った事ないな。
結構、根が深い拡張になりそうだからそれ位はいいと思うけどね。
一回やっちゃうと、どんどんやっちゃうから抑制のためかねぇ。
オートマトンの * とか closure だよね
>>891 独習C++も新しい版は<iostream>を使っている。
金はケチるな。新しいのを買え。
それにしてもなんで拡張子無しにしたんだろうか
つか拡張子なんていらね
おれはファイル名いらね
>>902 苦肉の策じゃまいか。
namespace って結構新しいと思ったし、今更名前かえても困る。
だから「.h 付き」は今までどおり、namespace なしのもの、
「.h 抜き」は namespace std に包んだものにしたとか。
標準化時の混乱が目に浮かぶわ。
906 :
デフォルトの名無しさん :2006/03/15(水) 00:34:09
>>905 いやその時にもうちょっとマシな命名法は無かったのかって話だ。
.hppとかあるじゃん
908 :
デフォルトの名無しさん :2006/03/15(水) 00:40:39
thisきーわーど
拡張子から離れることによって、ファイル名からヘッダ名へと抽象化されたのだ。 俺はそう思っている。
拡張子ないと不便だと気づかなかったのかな
ただのスイッチとしてコンパイラが認識するような形でもおkっていうのを明示したんだろ。
>>910 たぶん夢ばっかり見て現実を見てなかったんだろうな。
.h を取っ払ったのはアホもとい前衛過ぎ。
>>910 プリプロセッサがヘッダ名に拡張子を付けて実際のファイル名を決めるという実装でも問題ない。
VBとCの根本的な違いって、何ですか?
目的と設計思想
917 :
デフォルトの名無しさん :2006/03/15(水) 01:06:14
>>914 VB 色々楽=楽な分色々な知識が身に付かない
C 色々しんどい=しんどい分色々な知識が身に付く
918 :
デフォルトの名無しさん :2006/03/15(水) 01:11:00
#include 指令に指定されたリテラルがファイル実体を一意に識別するのは、ある条件を満たしている時のみ <iostream> で引用されるファイルに「拡張子がない」などと思いこんでいる奴は天然ぼけ
>>918 だからそれがアホ・・・もとい、前衛過ぎなんだって。
言語設計者はある程度夢を見ている方がバランスが良いと思う。
922 :
デフォルトの名無しさん :2006/03/15(水) 01:21:54
>>919 V
おまい、V=Rでないと前衛過ぎって手合いか?
>>922 V→Virtual
R→Real
であってる? まぁ、そうだとしてもなにがいいたいのかよくわからん。
とにかくに俺は .h を取っ払ったのは失敗もしくは時期尚早だったと評価している。
924 :
デフォルトの名無しさん :2006/03/15(水) 01:27:33
a.out の拡張子も取っ払うのは時期尚早か?
>>924 俺は gcc を使わないからどうでもいい。
やってみてしばらく経った今だから見えてくるものに対して 「今となってはあれは失敗だった」というならまだしも、 あとから見えてきたことを使って当時の決断をアホだの何だのってのは ずいぶんと卑怯な言いぐさではあるな。
>>926 いまとなってみれば当時の決断はアホだった、ってことだろ。
あんま上手な逃げ口上ではないなー
逃げ口上てw まじれすだが、過去を振り返って決断が誤りだった (決断の結果失敗した、ではない)と思うことはあるだろ? それを批判するのが卑怯か?
やってみなくちゃ分からないことだったなら、 別に当時の人がアホだったわけじゃないだろ。 当時の誰もが分からなかったんだから。 まあやらずとも分かることなら、批判されてしかるべきだが。
当時は誰もが無知だった。
932 :
デフォルトの名無しさん :2006/03/15(水) 09:08:48
いい具合いなカオスの中に、発展は存在する。
まあどういった批判かにもよるが、当時の状況も考えずに 結果だけを見て批判するのは卑怯だな
卑怯なんて語が出てくるところに信心入ってるな
すまん。拡張子がないとなんで不便なんだ?
936 :
デフォルトの名無しさん :2006/03/15(水) 11:58:26
ゲイツ教の敬虔な信者だろ
mime type の判別が・・・
ヘッダファイルごときに mime type の判定をする必要性はあまり感じないし、 仮にその必要があったとしても、実際には拡張子ありのファイルを置いておいて コンパイラが適当に判断して読みに行けばいいだけじゃん
その「適当な判断」も標準化せにゃならんのとちゃう。
拡張子は、そのファイルの内容についての「提案」であって、ファイルの内容を表しているとは限らないと思うけどな。 jpegで送ってほしいと頼むと、bmpの拡張子をjpgにして送ってくる人が後を絶たない。 拡張子など信用できない。 ヘッダ等に拡張子がなくて不便と思うのは、コードエディタ(具体的にはvimだが)で 構文強調表示を明示的に指定しないといけない点だな。 でも漏れテンプレートライブラリのヘッダは拡張子つけてないな。
ヘッダファイルは.hのみ。例外は許さんと言えないのがビョーンクオリティ
どうでもいいけど、そろそろ次スレの時期だね。
スレタイは「C++相談室 part48」
テンプレは
>>1-16 特に
>>9 、
>>15-16 に注意
標準ライブラリ・STLについての話題もC++相談室で扱う
非標準のライブラリ(Boost, Loki等)については他の専用スレ
であってるのかな
943 :
デフォルトの名無しさん :2006/03/15(水) 13:34:01
拡張子を入れると いわゆるハードコーディングになるから
んなアホなことを言ってるのはC/C++厨だけ
だからプリプロセッサがどうにかすればいいだけ。 あるいはiostreamというファイルの内容が拡張子付きのファイルをインクルードするだけと言うようにするとか。
んなの、シンボリックリンクでいいじゃん。
拡張子がないと make できません!いったい!私は!どうすれば!
別に拡張子無くても make できるけど。
拡張子無しのヘッダファイルをインクルードした拡張子無しのソースを コンパイルして、拡張子無しのオブジェクトファイルを生成し、 それをリンクして拡張子無しの実行ファイルを作る。
別に自前のヘッダは.h付きでいいじゃん。
>>929 気になった単語以外何も読まずにレスするのはどうかと思うぞ。
953 :
デフォルトの名無しさん :2006/03/15(水) 16:49:19
同じファイル実体に対して拡張子のない名前と拡張子のある名前を同時に持たせる方法を知らなかったり 拡張子に依存した運用形態に異常な執着を持っていたり、なんかたまんねーもんあるな
955 :
デフォルトの名無しさん :2006/03/15(水) 17:00:21
//Hello.java class Hello { public static void main(String[] args){ System.out.println("hello"); } }
ワロタ
>>926 当初からアホ・・・もとい、前衛過ぎると思ってましたがなにか?
まだ足掻くんだw
961 :
905 :2006/03/16(木) 11:29:23
そんなに拡張子無いのが嫌ならincludeの中のヘッダ、 全部自分でリネームしちゃえばいいじゃん。 他の人は納得してんだから、無用な労力を負うべきだとすれば君ヒトリだ。
>>961 君の頭も相当アホ・・・もとい、前衛的だねぇ。
独りで必死に標準規格に抗うもまた良し
てか、お前らのなんなの? 一方は拡張子を取っ払ったことをアホだって言ってるだけだし、 もう一方も拡張子を取っ払ったことはアホだと認めてんだろ? 意見が同じなのになんでもめるの?
965 :
デフォルトの名無しさん :2006/03/17(金) 00:39:47
アホちゃいまんねん、パーでんねん
プログラマはコミュニケーション取るのが下手糞なんだよ
>>964
967 :
デフォルトの名無しさん :2006/03/17(金) 01:11:50
拡張子なしとhppってどうやって使い分けたらいいの?
知るか そのファイルを作ったやつに聞け
世の中にはアホしかいないから どいつもこいつも俺の思う通りに動かない
.h でも .hpp でも拡張子なしでも、統一さえとれてれば何でもいいよ。
いちいちヘッダファイルとか作成するのマンドクセ
972 :
デフォルトの名無しさん :2006/03/17(金) 07:57:01
973 :
デフォルトの名無しさん :2006/03/17(金) 09:46:05
.hpp は本当は保証外
974 :
デフォルトの名無しさん :2006/03/17(金) 10:09:52
975 :
デフォルトの名無しさん :2006/03/17(金) 10:16:35
hとhppの違いが分かりません
3倍もタイプ量が違うじゃないか
978 :
デフォルトの名無しさん :2006/03/17(金) 10:46:42
俺の友人なんて myclass.inc とかにしてるぞ(笑
M$が.hを推奨してるのは明らかだしな
先見性が無いと言えば文字コード JISもCP932もUCS-2もBOMも今思えば超アホなコード
981 :
デフォルトの名無しさん :2006/03/17(金) 11:05:04
半角カナをあんなとこに持ってったのは当時のハードだしあれだが、 いまだに引きずってるのがあほらしい。
983 :
デフォルトの名無しさん :2006/03/17(金) 11:36:22
incってアセンブラっぽ。
クラスについての質問 クラスのメンバ関数の引数のあとにconstが付いてるんだけれど、どういう意味? 自分の持ってるC++入門書には書いてなかった void Function() const←コレ
>>985 constなインスタンスについてそのメンバを呼べる、ということ。
const X x;
x.Function();
987 :
デフォルトの名無しさん :2006/03/17(金) 16:11:51
>>985 そのメソッドの中でそのクラスのメンバ変数を
変更しませんよ、ということを宣言している。
なので変更するようなコードを書くと怒られる。
989 :
デフォルトの名無しさん :2006/03/17(金) 16:43:24
>>988 どちらも同じことを言っているようにしか見えないが。
立場が違うけどなw
991 :
デフォルトの名無しさん :2006/03/17(金) 17:10:52
>>990 うむ。
>>989 が理解できれば const は一応分かったことになるが、
const はそれだけで5杯くらいメシが食えちゃうくらい味わい深いからな。
constメソッドの中でSTLコンテナ使おうとしてハマるに1票
993 :
デフォルトの名無しさん :2006/03/17(金) 17:39:05
int main(const int argc, const char* const* const argv) { 処理 } で、 boost::program_options を使おうとしてハマった。 なんで両方とも const とらなきゃならんのだよぉ
994 :
デフォルトの名無しさん :2006/03/17(金) 18:04:48
argc は確かに変だけど、argv は仕方ないだろ ISO/IEC14882 3.6.1 Main function ではっきり非 const とされている
995 :
デフォルトの名無しさん :2006/03/17(金) 18:10:40
>>994 どうせ argc は値渡しだろうし、
argv の方で怒られてたんだろうな。
そうか、規格で非 const とされてたか。
それは知らなかった。
ていうかおまいはどこでconstとして覚えたんだ
997 :
デフォルトの名無しさん :2006/03/17(金) 19:35:26
>>996 わかんね。
たぶん人からもらったソース(笑
>>994 おいおい,嘘いっちゃいかんよ.
3.6.1 の 2 に「It shall have a return type of type int, but otherwise its type is implementation-defined.」とあるように,戻り値だけは決まってるけどあとは実装による.const を許す実装があったってかまわない.
>>998 多分、
>>994 の真意は、「規格で明示的に認められているmainの型は引数にconstがついていない」ということだろう。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。