1 名前:デフォルトの名無しさん mailto:sage [2008/05/27(火) 23:53:59 ] C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレに お願いします。 前スレ C++相談室 part61 pc11.2ch.net/test/read.cgi/tech/1205059063/
231 名前:デフォルトの名無しさん [2008/06/13(金) 14:00:53 ] A.hで中身まで記述した static void Func() { ・・・ }; を B.cpp、C.cppそれぞれでインクルードすると実体はそれぞれにできるんでしょうか?
232 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 14:02:42 ] >>229 >227
233 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 14:03:33 ] >>229 C++/CLIはC++を拡張した別の言語としてEcmaで標準化されてるよ。
234 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 14:03:59 ] >>231 はい。但し、そのFunc()を例えばB.cppでは使いC.cppでは使わなかったとすると、一つだけになるかもしれません。 # 勿論、どちらでも使わない場合は一つもないかもしれないわけで。
235 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 14:05:25 ] まぁそれをやるならせめて無名名前空間をつかってほしいところ
236 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 14:13:59 ] >>234 うわぁぁ。そうなんだ。 staticつければ必ずひとつになると思っていました。ありがとう。 こういう場合ひとつだけにするにはテンプレートにするしかないのかな。 ヘッダに記述すること自体の是非は別として。
237 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 14:19:46 ] >>236 いや、テンプレートにするかしないかとstaticかどうかは別の問題だから。 つーか、>231の場合でもどうせインライン展開されるから消えてなくなると思うし、 テンプレート関数にしたところでインライン展開されなければ複数できてもおかしくはない。 で、一つにしたい積極的な理由があるの?
238 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 14:42:06 ] いろいろ言われそうだけどVCのプリコンパイル済みヘッダーの#include <stdafx.h> が嫌だからなんです・・。 いろいろなコンパイラで使えればな〜と思っていたらどうしてもこれが邪魔で。 プリコンパイル済みヘッダーの設定変えればいいのでしょうけど、ファイルをコピー、 includeですぐに使えるような書き方はないかな〜と。
239 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 14:50:41 ] あ、見当違いなこと書いてたかも。 上記理由でどうせ同じ関数なんだからひとつにしてファイルサイズ減らせないかなと 思っていた次第です。
240 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 14:52:05 ] >>239 理由がそれだけなら、最適化するとどうせインライン展開されて消えてなくなるから気にするな。
241 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 15:27:25 ] というか、あちこちに同じ中身が生成されるわけだから ファイルサイズは逆に増えるよね。
242 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 15:33:47 ] う〜ん、いろいろありがとう。 とりあえず最適化に任せてみます。
243 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 16:11:17 ] ===foo.h=== #include "bar.h" class foo { (略)// barは出てこない }; ===foo.cxx=== #include "foo.h" (略)// barが出てくる とやるのと、 #include "bar.h" をfoo.cxxの中に持ってくるのは、 どちらにどういうメリットデメリットがあるのでしょうか。 また、一般的にはどちらの書き方が推奨されますか。
244 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 16:13:13 ] CLIって便利だよな 特に他言語で作ったクラスライブラリがそのまま使えるお得感は感動ものだ
245 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 16:17:15 ] >>243 ヒント:依存関係、カプセル化
246 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 17:46:14 ] >>243 後者。素直に使う所に書く、で必要十分。 前者にメリットは無い。fooを使うやつのコンパイルがbar.hの分遅くなるだけ。
247 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 18:14:43 ] 次のプログラムをエラー無くコンパイルしたいのですが、方法を教えてください。 //データの構造体----------- struct dataA { int m_dataA; CLSA * m_next //クラスのポインター }; //使用するクラス------------ class CLSA { dataA m_dat[100]; //データの配列 }; dataAの中にクラスのポインターを持つ。この状態ではCLSAが無いと言われます。 順番を変えるとクラスの中でdataA構造体が無いと言われます。 対処方法が無いでしょうか?
248 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 18:16:41 ] セミコロン抜けてた CLSA * m_next; //クラスのポインター
249 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 18:32:36 ] >>247 struct dataAの上に 「class CLSA;」を書く。 あと、どうでもいいけど何かよく分からないデータ構造だな。 dataA{ CLSA* m_parent; } とか dataA{ dataA* m_next; } とか CLSA{ CLSA* m_next; } なら分かるけど。
250 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 20:00:26 ] 出来ましたありがとうございます。基本的な内容ですねorz データ構造は root クラスインスタンス | |-ノード1クラスインスタンス | : |-ノード1クラスインスタンス | : |-ノード1クラスインスタンス | : |-ノード1クラスインスタンス のような多段構造のようなもので、ノード分岐の意味をdataAの内部で示しています。 意味自体が単独で作られたり渡されたりするので、1つの構造体にしています。
251 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 20:08:54 ] >>244 そのままシームレスに使えればだがな。 だが現実は・・・・ ハァー
252 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 22:04:32 ] >>222 3.9.1 p1 は「バイト中のすべてのビットが値に反映される」とはいっても、ビット列と値が 1 対 1 でないこともあるんじゃないかな。 例えば char が符号付きで符号ビットと絶対値で表現する場合、値 0 を表現するビット列が 2 パターンある。その処理系で char* を通して値 0 を読み、その値を char* を通して書く とビット列が変わる可能性があるんじゃないかな?
253 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 00:03:39 ] char型のコピーはbit列をそのままコピーすると言っているのでは
254 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 04:05:09 ] >>252 現行の規格で多少無理やり解釈すれば、 -0 と +0 は == で比較すれば 同じになるとしても、区別可能な(異なる value representation を持つ)二つの値 ということでコピーでビット列が変わる可能性は無い、とは言えそう。 ちょっと苦しいんで調べてみたところ、 C との互換性と合わせて見直しが 提案されているみたい。 www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2631.html この中で C99 の規格を基本的にはそのままパクりながら、 C99 では 保証が無いものの、 C++ で半ば慣習的に行われてきた char による object representation のコピーを保証するため、以下のような記述の追加が 見られる。 The types unsigned char and char may be used for “bitwise” copy. [Note: this means that if signed char has a negative zero which is either a trapping value, or will be forced to positive zero on assignment, plain char must be unsigned. ?end note] てきとう訳: 型 unsigned char と char は「ビット的」コピーに使ってもよい。 [注: これは、もし signed char が負のゼロをトラップ値として持つか 代入において正のゼロに強制されるのであれば、ただの char は unsigned でなければならない、ということを意味する。 -注ここまで] 提案とは別に、議論の中では C++ では2の補数を強制してしまうような話も 出ていたらしい。実際のところはそれでもいいのかもしれない。
255 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 13:48:22 ] 以下のような二種類の構造体のフィールドなのですが、 どちらがより適切なのでしょうか? struct A { int length; // textの長さ unsigned char text[0]; // 利用者側で好きに領域を確保して先頭を格納。 }; struct B { int length; unsigned char text[1]; }; 違いはtext[1]とtext[0]だけなのですが、 text[1]としてしまうと、 unsigned char text[] = "aiueo"; A* a = (A*)malloc(sizeof(A) + strlen(text)); としたときに(処理系依存ですが) intで4バイト、unsigned charがパディングされて4バイト さらに文字列の長さで5バイト確保されます。 これだとunsigned charがパディングされた4バイトは無駄な領域の気がします。 text[1]とするメリットはあるのでしょうか?
256 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 14:12:25 ] >>255 宣言より大きい配列のアクセスはお勧めできないと思う。 環境依存なしでそういう構造を作りたいなら struct A { int length; // textの長さ }; A* a = (A*)malloc(sizeof(A) + strlen(text)); で確保して char* buff=(char*)(a+1); で文字列にアクセス 文字列の構造体を作りたいなら以下の方がお勧めかな struct A { int length; // textの長さ unsigned char* text; };
257 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 14:24:31 ] >>255 unsigned char text[0]; はC89では認められていない。 C99から導入されたflexible array memberを使うなら、 unsigned char text[];
258 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 14:58:10 ] >>254 なるほど。 今回初めてC++の仕様書に目を通してみたけど未定義や処理系定義の部分が多くて 正確に解釈するのははなかなか難しいですね。 現状の処理系に合わせて処理系定義の部分を削っていけばかなりシンプルになると 思いますけど。
259 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 15:18:36 ] >>258 処理系を前提とした入門書を読もう。 処理系未定義はその後で。
260 名前:255 mailto:sage [2008/06/14(土) 19:20:57 ] >>256 さんどうもありがとうございます。 struct A{ int a; unsigned char c[0]; }; gcc -c -pedantic test.c としたら警告が出ました。 警告: ISO C forbids zero-size array 'b' gccの独自拡張で可能になっているけれどC89自体では禁止されている ということですね。
261 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 20:30:10 ] おい、お前ら、googleでソースコードの検索ができることを知ってましたか? www.google.co.jp/codesearch
262 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 20:31:46 ] お前が今まで知らなかったことに驚愕。
263 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 20:32:49 ] どういうときにつかうん
264 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 20:34:41 ] codeをsearchする時
265 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 20:54:24 ] >>261-264 自演乙
266 名前:デフォルトの名無しさん [2008/06/14(土) 20:56:31 ] >>265 自演じゃねーよ、タコが
267 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 20:58:47 ] >>266 イカですけど何か?
268 名前:デフォルトの名無しさん [2008/06/14(土) 20:59:26 ] >>267 創価、すまんかった
269 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 23:11:26 ] # include<iostream> using namespace std; void func(int a = 0,long int b = 1000, double c = 2.9751) { cout<<"This is func[i].\n"; cout<<"a="<<a<<", b="<<b<<", c="<<c<<"\n\n"; } void func(int a,double b =3.4152) { cout<<"This is func[ii].\n"; cout<<"a="<<a<<", b="<<b<<"\n\n"; } void func(long int a) { cout<<"This is func[iii].\n"; cout<<"a="<<a<<"\n\n"; } int main(void) { func(0,1000,2.9751); func(0,3.14152); func(0); return 0; } オーバーロード関数が呼び出せませんと言うエラーが出るのですが、 何処が間違えているかわかりませんか? 未熟な私に教えていただけたらありがたいです。
270 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 23:16:36 ] そんな かわいそうな つかいかたを するな
271 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 23:22:17 ] >>269 どれを呼んでいいのかワカンネ。とコンパイラ様は仰っておられる
272 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 23:23:24 ] >>269 とりあえず、2個目と3個目のfuncを関数ごと コメントアウトして実行してみ。
273 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 02:27:52 ] もう引数全部意図する型にキャストしちゃえよ
274 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 02:40:25 ] 既定引数と多重定義は「まぜるな危険」だろ。 危険といっても、だいたいコンパイルエラーか警告だけど。 必要なら既定引数を使わないで多重定義をがんばることもやる。 といってもこういうのはありにしているが。 void f(int x); void f(double x); void f(int x, int y, int z = 0); //実引数1個なら多重定義の解決の候補に既定引数は関係しない。 //実引数2個ならデフォルト引数を使うがfの候補は1つに決まっているので良し。
275 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 03:02:24 ] fcloseの定義はどこにあるのでしょうか? glibc-2.7のソースの中には無いようなのですが…
276 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 03:07:07 ] libio/stdio.h
277 名前:275 mailto:sage [2008/06/15(日) 03:16:44 ] >>276 ありがとうございます! あった!なるほど#defineされてたわけですね。 #define fclose(fp) _IO_new_fclose(fp) で、_IO_new_fcloseをたどっていくと 最終的に__closeという関数が呼ばれているようなのですが、 今度こそ定義がglibcにはありませんでした。 ここから先はどうやって追えばよいのやら…
278 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 03:17:10 ] >>275 マクロになってるとかじゃないの?
279 名前:275 mailto:sage [2008/06/15(日) 03:22:33 ] すみません__closeありました。 sysdeps/march/hurd/close.c にありました。 実は、fcloseするときにバッファをディスクに同期する 部分がどうなってるのかを追いたかったのですが、 __closeから先はどうやら単にクローズしているだけのようです。 追いなおします。
280 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 03:25:42 ] >>277 それはシステムコールじゃないかね。 そうだと、カーネルのソースを見る必要がある。
281 名前:277 [2008/06/15(日) 13:41:18 ] >>280 ありがとうございます。 Linuxのソースを見てみました。 linux/include/asm-i386/unistd.h の中に #define __NR_close 6 というのがあって、 linux/arch/i386/kernel/syscall_tables.S の中のテーブルの6番の位置は sys_close となっていたので、sys_closeで探すと linux/fs/open.c の中にあって、その中で呼んでいる filp_close の中でflushとかやっていました。 ただ、__closeから__NR_closeのつながりがわかりませんでした。 これをどこかで#defineされているものなのでしょうか。
282 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 13:58:38 ] C++のスレで話すような話題か、っつーのは置いといて... 今時のOSだと、ユーザアプリがファイルをcloseした からといって、いちいちディスクに同期は取らんと思うけど。 libcのfclose()は、fflush()を呼ぶなりして、少なくとも ユーザアプリ(というかlibc)が握ってるデータがkernel側に渡るようにはする。 が、kernel側がダーティページをどう処理するかは、バッファキャッシュ管理の 問題になるんでは。 ぶっちゃけsyncとかがあるのはそのためでしょ。
283 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 22:44:48 ] class A { A(); ~A(); A(const A&); void operator=(const A&); friend class X; }; class X { class Impl; Impl* impl_; }; ユーザから見て A オブジェクトの生成と消去を X からしかできないようにしたいけど impl_ の中で A を何らかのコンテナで管理するとき、そのコンテナは A と friend で はないので A のコンストラクタとデストラクタを呼び出せません。A の中に実装のため のクラスを friend として並べたくないし、実装の変更のたびに変更したくありません。 何か簡単に解決する方法はあるでしょうか?
284 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 23:10:00 ] >>283 class A を class X か class X::Impl の private メンバにする。
285 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 00:39:28 ] >>284 もちろんユーザは A の public メンバにアクセスできることが前提です。
286 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 00:57:47 ] >>285 A を抽象インターフェースにして実体を >284
287 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:12:34 ] template hackerさん。ヘルプミー。 template < class _T > class C { public: template < class _Ta > void X(); }; template < class _T > void F() { C< int > obj1; obj1.X<int>(); C< _T > obj2; obj2.X<_T>(); }
288 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:13:57 ] めっちゃ途中で書き込んだ。さーせん。 その上のコードの、obj2.X<_T>();がコンパイルエラーで通りません。 何ででしょうか 代替案とかあるでしょうか
289 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:21:27 ] 環境とエラーメッセージくらい書こうぜ
290 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:29:17 ] ったりめーだろ class _Tの実体がない
291 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:29:37 ] じゃなかったclass _Tの定義がない
292 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:33:42 ] >>286 ああ、その手があったね。 しかも A の唯一の派生クラスを A の friend にしておけば抽象である必要もないし X の中に入れる必要もないね。 ありがとう。
293 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:34:00 ] >>290 _Tはテンプレート引数だろ。
294 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 01:57:05 ] >>288 obj2.template X<_T>(); その名がテンプレートであることを示せ >>289 この場合はいらんかも
295 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 02:02:54 ] >>294 >>287-288
296 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 02:21:21 ] >>287 予約識別子死ね。
297 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 02:25:06 ] >>292 > しかも A の唯一の派生クラスを A の friend にしておけば抽象である必要もないし > X の中に入れる必要もないね。 何か変だな。一般的には、抽象でいいものに実装を混ぜる必要もないし、 スコープを無駄に広める必要もない、となりそうなもんなんだが。 まぁ望むものは得られたみたいなんで、書き込みに出てない部分の都合があっての 話ならどうでもいいけど。
298 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 07:38:23 ] これでいいんだよね? class A { public: virtual ~A() { } virtual void Foo() = 0; }; class X { public: X(); A* NewA(); private: class Impl* impl_; }; class X::Impl { public: A* NewA() { return new AImpl; } private: class AImpl : public A { public: virtual void Foo(); }; }; X::X() : impl_(new Impl) { } A* X::NewA() { return impl_->NewA(); }
299 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 12:39:10 ] >>297 抽象にしたくないのは単に性能のため。 Aは単純なクラスを想定しているのでそれほど実装を隠す必要はないから。 もしAの実装を隠したい場合はImpl方式にするかもしれない。 抽象クラスより優れている根拠は特にないが。 確かにAの派生はXに入れたほうが名前空間の汚染を軽減できるね。 >>298 デストラクタは private にしてユーザが削除できないようにしたい。 さらに特定のクラスにしか派生できないようにしほうが何となく安心。
300 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 12:47:35 ] obj2.template X<_T>(); いや本当は知らないんですけどね
301 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 23:02:51 ] >>294 >>300 thx。たすかりますた。thx。 >>287 解った。死ぬから_Tを使わせてくれ。
302 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 23:03:51 ] > _T 処理系の予約語じゃねえか・・・
303 名前:デフォルトの名無しさん [2008/06/17(火) 21:38:29 ] ワラタ
304 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 23:47:32 ] class x について ++x と x++ を定義する場合 operator++ はどうなるのかしらぁぁぁぁぁぁぁぁ
305 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 23:53:14 ] ++x → operator++() x++ → operator++(int) 後者の引数はオーバーロードのためのダミー引数で、 それ以外の何かに使う物ではない。
306 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 23:55:50 ] X & X::operator ++ (void) ; X X::operator ++ (int) ;
307 名前:304 mailto:sage [2008/06/17(火) 23:59:07 ] ありがとうございました。orz
308 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 07:40:42 ] 関係無い話だけど、 テンプレート引数型で後置インクリメント使う馬鹿は氏ねと言いたい。
309 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 07:56:32 ] いやむしろ型特性を利用して組み込み型のときだけ後置インクリメントにするという手も
310 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 13:14:00 ] VC++ の2005を使用し、C++/CLIでアプリを作成しています。 ListViewに複数項目が登録されている場合、最下段での下キー押下で最上段へ、 また、最上段での上キー押下で最下段にフォーカスを移したいと思っています。 これをやるだけならキーイベントを拾って 「最下段で下キーが押された場合、フォーカス位置を0にする」 というようにすればいいのかと思ったのですが、ListViewのデフォルト機能(?)で 上下キー押下はフォーカス位置を1つずらすようになっています。 つまり、 1 2 3←フォーカス この状態で下キーを押すと、フォーカス位置が0に戻る処理が実行された後、 フォーカス位置が1つ下にずれてしまうので 1 2←フォーカス 3 となってしまいました。 ListViewが持っているデフォルトのキーイベントを破棄できればいいのかと思ったのですが、 その捨て方も分かりませんでした・・・。 上記要件を満たす方法などがありますでしょうか?
311 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 13:39:20 ] スレ違い .NETスレ行け
312 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 13:39:59 ] >>310 C++/CLIはC++を元にした別の独立した言語です。 なので基本的にはC++/CLIスレで質問して下さい。 しかし、言語自体でなく、 ListView(.NETコンポーネント)のことなので、 .NET総合スレか、人の多い(+構文が近い)C#スレをお勧めします。 System.Windows.Forms.ListView などは C++/CLI, C#, VB.NETで同一のものです。
313 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 13:52:12 ] 次スレのテンプレには、 C++/CLI関連の誘導を加えた方がよさそうだな
314 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 14:25:33 ] >>311 、312 失礼しました 他スレにて再質問します ありがとうございました
315 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 14:53:55 ] 以下のプログラムで、ddd() の中のようなキャストを行ってから bbb() の中で B::f() を正しく 呼び出せるでしょうか? struct B { void f(); }; struct D : B {}; void bbb( B* b[], int size ) { for ( int i = 0; i < size; ++i ) b[i]->f(); } void ddd( D* d[], int size ) { bbb( static_cast<B**>( static_cast<void*>( d ) ), size ); }
316 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 15:46:32 ] ちょっと聞いてください。 enumハックを使ってクラスの中でSIZE_MAXという名前の定数を定義したんですよ。 そしたら、「error C2143: 構文エラー : '}' が '定数' の前にありません。」などのエラーが何個か出ました。 いろいろコメントアウトして原因を探ったら、vectorやstringなどをインクルードするとエラーが出る事がわかったんです。 で、インクルードファイルが壊れてると思い、再インストールしたんですが直らず、 結局、limits.hでSIZE_MAXという名前のマクロが定義されていたのが原因でした。 エラーメッセージに名前は出ないし、ネームスペースも無視される。 マクロって最低じゃないですか?
317 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 16:00:25 ] マクロのない言語に乗り換えるといいと思うよ
318 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 20:39:42 ] >>316 だからマクロは大文字を使うんだよ。
319 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 21:15:33 ] やってみて結果を述べるのが自立した大人の行動と思う。
320 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 21:15:56 ] 319はto315
321 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 21:21:24 ] だから、大文字の識別名はマクロ名以外には使わないという お約束があるんだよ。
322 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 21:46:10 ] >>319 すみません。特定の環境ということではなく一般的にできるかどうかです。 VC8で試したら動きます。
323 名前:デフォルトの名無しさん [2008/06/19(木) 22:37:03 ] やってみた結果から刷り込まれた処理系依存な「知識」が豊富な「大人」は痛いよな
324 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 22:44:01 ] >>318 ,321 列挙型や定数に大文字使ってるのよく見かけるけどそんなお約束あるの?
325 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 22:51:45 ] >>324 定数もマクロだったりするし、列挙型はスコープ無いから定数の代わりに使ったりするから
326 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 23:29:25 ] std::wstring以外で、汎用的な文字列クラスって言うと何になるんでしょうか。 今までずっとATL::CStringWでやっていたのですが、std::wstringはいまいち不便で。 boostあたりになっちゃうんでしょうかね。
327 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 23:49:29 ] >>325 >定数もマクロだったりするし、 定数をマクロで書くのはよくないんじゃない? Effective C++ 1項に書いてあるように、これこそお約束なのでは。 >列挙型はスコープ無いから定数の代わりに使ったりするから >>316 の例だって列挙型を定数がわりに使ってハマってるように見えるんだが、何か違う?
328 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 00:13:55 ] 怪しかったらundef CreateWindowとか
329 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 00:35:20 ] 質問です。 あるクラスのインナークラスを他のファイルで前方宣言したいと思っているのですが どのように宣言すればよいのでしょうか…。 以下例です。 名前空間SpaceAに定義されたクラスClassAがあったとして ClassA内部にはInnerClassAが定義されているとします。 namespace SpaceA { class ClassA { public: class InnerClassA{} } } このInnerClassAを他のファイルClassB.hで前方宣言して使うことはできるのでしょうか…。 // 前方宣言 namespace SpaceA { class ClassA; //struct ClassA::InnerClassA; // ClassAは名前空間じゃないからエラー…どう書けばいいのか } using SpaceA::ClassA; namespace SpaceB { class ClassB { public: ClassB( InnerClassA* p ); // イメージ的にはこんな感じで使いたい } } よろしくお願いします。
330 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 01:44:36 ] >>315 D* を B* としてアクセスするのは、規格の 3.10 p15 にあるエイリアスの制約に 違反するので、未定義動作。 ddd() の引数に B* の配列を似たようなキャストしてねじ込んだ場合は、上記の 制約を満たすことになるのでセーフ。
331 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 01:48:50 ] >>329 無理。外側の ClassA の定義が必要。 ClassA の中で class InnerClassA; としてあれば InnerClassA の定義は必要ない。