おつかれさん
強引にSTLスレを独立させる気だな。 標準ライブラリのそのまた一部の機能だけ スレを分割するなんて意味ないぞ。
STLつかうと一気に実行ファイルサイズが10倍に?!
環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない。
すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
#include <stdafx.h> 後氏ね。
言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。
>>15 と
>>16 の間
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?
ったく、スレもまともに立てられねえのかよ。クズが。
list末尾に要素を追加し、次にその要素を操作しようと思っています。 管理の楽さから、ポインタを渡さない様にしようと思い、つまずきました。 コンストラクタに引数が無い場合は、どう末尾に生成すれば良いのでしょうか #include <list> struct TestA{ int hoge; TestA( int n ){ hoge = n; } }; struct TestB{ int hoge; TestB(){ hoge = 3; } }; int main(){ std::list<TestA> list_test_a; list_test_a.push_back(7); TestA& test_a = list_test_a.back(); printf( "%d\n", test_a.hoge ); std::list<TestB> list_test_b; TestB& test_b = list_test_b.push_back(); //エラー printf( "%d\n", test_b.hoge ); return 0; }
push_back(TestB());
27 :
25 :2005/04/14(木) 12:52:31
「リファレンス」の配列は作れないのかな。 int x = 0, y = 0, z = 0; int &rx = x, &ry = y, &rz = z; // reference of int int* p[] = {&x, &y, &z}; // array of pointer to int int& r[] = { ... }; // array of reference to int
>>28 ISO/IEC 14882:1998
8.3.2.4
「There shall be no references to references, no arrays of references,
and no pointers to references.」
31 :
デフォルトの名無しさん :2005/04/14(木) 17:39:14
>>18 俺もC1010出る。
ちなみに#include "stdafx.h" は全部に入ってる。
他の原因ってないっすか?
35 :
デフォルトの名無しさん :2005/04/14(木) 17:55:14
>>34 ""も<>もやってみたけどダメでした。
ちなみにやった事は、アプリケーションWIZでWIN32アプリを作り、
それにcppとhを1つづつ追加しただけす。
追加したソースは他のアプリで使ってたんで問題ないと思います。
という感じです。
>>33 テンプレちがう。
36 :
デフォルトの名無しさん :2005/04/14(木) 18:02:11
すんません。直りました。 ヘッダーのinclude行より前に書いたら直りました。 ごめんなさい。
37 :
デフォルトの名無しさん :2005/04/14(木) 20:06:29
マクロに渡された引数が定数かどうか 判断するにはどうしたらいいのかな?
v(^・^)v
>>30 と関連するけど
参照メンバに対してoffsetofを使おうとすると、鼻から悪魔が。
まあ、大抵の実装でぬるぽ。
マクロを処理するプリプロセスの段階では構文解析はしないしな
カエサルの物はカエサルへ マクロの物はマクロで
>>39 メンバの型は直接関係無くて、POD以外の型にoffsetof使った時点でアウト。
44 :
デフォルトの名無しさん :2005/04/15(金) 01:27:02
メモリリーク関連のテクニックだけ扱った書籍というのはあるのでしょうか? メモリリークを検知するツール何が一番よいと思いましたか?
漏れは仕事ではBoundsChecker使ってるけど 自前の時はVCランタイム任せ…
気にするな、年とともに漏れなくなる。
寧ろ漏れ易くなるような……
(−ω−)
51 :
デフォルトの名無しさん :2005/04/16(土) 21:19:46
参照渡しって結局なにを渡してるんですか?
アドレス
なんのですか? オブジェクトですか? オブジェクトなら入れる入れ物はポインタじゃないんですか?
54 :
53 :2005/04/16(土) 21:32:11
失礼、↑は53です。 さらに、ポインタじゃなくてポインタ変数でした。
値渡し、参照渡し、名前渡し、矢切の渡し さて無いのはどれだ?
必要呼び出し
>>53 メモリに「なにか」が格納されている領域の先頭アドレス。
ポインタ渡し a = &b + &cとかいやだから作ったってはげが言ってた
住所を書いた紙をコピーしたと思えばよろし
>>58 それをいうなら *a = *b + *c がいやだから、じゃないか?
>>51 文字通り参照を渡してるんだよ。アドレスとかなんとか余計なことは考えなくてよろしい。
実態はポインタ渡してるのとほぼ同じ。
>>59 コピーしたらまずいんでね?オブジェクトの場合。
>>63 「アドレスを保持した変数をコピー」と読み替えるんだろ。何かまずいか?
より分かりづらいという意味でならまずいかも
でも、実質、アドレス私。
禿も関数は参照渡しよりポインタ渡しを使えと言ってるしな
back_inserterってエロくない?
人間は学習しない。
std::back_inserter スタンディング・バックインサーター
つまんね
std::back_inserter sexually transmitted diseases・back inserter
Boost の Sandbox Files に、次期標準ライブラリに組み込まれる予定の ライブラリ一覧( Boost-TR1 )が加わってるみたい。 現在 std::tr1 名前空間が利用されている模様
76 :
デフォルトの名無しさん :2005/04/20(水) 14:28:05
あ、でも… <hash> が無いから、unorderd_map と、unorderd_set が無いのか
78 :
デフォルトの名無しさん :2005/04/20(水) 23:33:18
ビット演算で変数と定数で結果が異なるんだが、なぜ? (VC6,VC7.1,GCC3.4.3) #include<iostream> #define print(x) {for(int i____=0;i____<32;i____++){ \ std::cout << (((static_cast<unsigned long>(0x00000001) << (32-1-i____)) & x) != 0);} \ std::cout << std::endl;} int main() { print( ((0xFFFFFFFFU >> 32) << 32) );//00000000000000000000000000000000 unsigned int uu1 = 0xFFFFFFFFU; print( ((uu1 >> 32) << 32) );//11111111111111111111111111111111 }
これはおもしろい。 というかall 1になるのは反則だな。
80 :
78 :2005/04/21(木) 01:10:19
型のbit数以上のシフトの結果が保証されてナインかな...。 #define LSHIFT(data,N) ( ((N)<sizeof(data)*8) ? ( (data) << (N) ) : (0) ) #define RSHIFT(data,N) ( ((N)<sizeof(data)*8) ? ( (data) >> (N) ) : (0) ) で対処するか... unsigned int uu2=1; print( ( 1 << 31 ) );//1000000000000000000000 print( ( uu2 << 31 ) );//1000000000000000000000 print( ( 1 << 32 ) );//0000000000000000000000 print( ( uu2 << 32 ) );//0000000000000000000001 print( ( 1 << 33 ) );//0000000000000000000000 print( ( uu2 << 33 ) );//0000000000000000000010 print( ( 1 << 34 ) );//0000000000000000000000 print( ( uu2 << 34 ) );//0000000000000000000100 std::cout << "----------------------" << std::endl; print( ( 1 >> 31 ) );//0000000000000000000000 print( ( uu2 >> 31 ) );//0000000000000000000000 print( ( 1 >> 32 ) );//0000000000000000000000 print( ( uu2 >> 32 ) );//0000000000000000000001 print( ( 1 >> 33 ) );//0000000000000000000000 print( ( uu2 >> 33 ) );//0000000000000000000000 print( ( 1 >> 34 ) );//0000000000000000000000 print( ( uu2 >> 34 ) );//0000000000000000000000
上のほうはコンパイル時に((0xFFFFFFFFU >> 32) << 32)が展開されて 0にされているのかな。
82 :
81 :2005/04/21(木) 01:13:13
あ、上のほうはこれで問題ないのか。すまん。
BCC 5.5.1 は両方とも 11111111111111111111111111111111 になった
> 型のbit数以上のシフト そりゃダメだろー
ttp://www.kuzbass.ru/docs/isocpp/expr.html#expr.shift "The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand."
結果の値が実装定義かと思ってたが、未定義動作になるそうだ。
32bitCPUなら、シフト命令のオペランドが下位5ビットしか見られなくて、
32ビットのシフトが0ビットのシフトになる、というのが考えられる。
定数の場合はコンパイラが内部で計算するので、CPUの特性を反映しないんだろう。
> 下位5ビットしか見られなくて 80386以降がそうだったかなー
88 :
デフォルトの名無しさん :2005/04/21(木) 16:46:15
tryでgetsで得た値が配列を超えていた場合でもエラーが起きないようにしたいのですが、 tryが認識されません。 なぜでしょうか? コードは長いので2回に分けて書きます void mo12(void){ char str12[5]={0};/*結果を入れてもらう変数*/ int strbl;/*strlenghtの結果を入れる為の変数*/ putchar('\n'); for(;1;){ printf("\t文字を入力してください(zで終了):"); try{ gets(str12);/*値を取得してstr12に格納*/ }catch(...){ printf("エラー"); break; }
89 :
デフォルトの名無しさん :2005/04/21(木) 16:47:29
>>88 の続きです
//str12[0]='z';
strbl=strlen(str12);//文字の最大数を測定
//元の値の表示
if(strbl>5){er=-3;error1(&er);break;}
putchar('\t');
for(i=0;i<strbl;i++){printf("%X ",str12[i]);}
printf("が入力されました\n\t");
for(count=0;count<strbl;count++){
er=mondai12(str12,count);/*文字をHEXコードに変換し、上位ビットと下位ビットを入れ替える関数*/
if(er<0){/*エラー処理*/error1(&er);}else{
//結果の表示
if(count==0){/*最初のみ表示*/printf("上位ビットと下位ビットを入れ替えると");}
printf("%X ",er);
}
}
printf("\n\n");
for(count=0;count<strbl;count++){/*大文字か小文字のzを検索該当する値があれば-5をerに代入*/
if(str12[count]==0x7a||str12[count]==0x5a){
er=-5;}
}
if(er==-5){break;}
}
}
おいおい、点々とするばかりで片っ端からレスを無視か?
>>88 お前のごみみたいなコードを何回も見ているこっちの身にもなってくれ。
つーか、根本的にC++(というよりCでさえ)理解できていない悪寒。
VBやってる方が幸せだと思われ。
92 :
デフォルトの名無しさん :2005/04/21(木) 16:54:48
>>91 解決しました、ご迷惑をおかけしてすみませんでした。
スレを3つも巻き込んでしまってすみませんでした。
マルチポストでスレ汚した挙句、「解決しました」の一言だけ。 せめてどうやって解決したのかくらい書けばまだ許せたのに。
94 :
デフォルトの名無しさん :2005/04/21(木) 17:32:01
>>93 .cの拡張子でコンパイルしていたのでtryが機能しませんでした。
.ccpに変えると上手くいきました。
解決方法を書かなくてすみませんでした
96 :
デフォルトの名無しさん :2005/04/21(木) 21:24:02
new演算子について考えすぎてハゲそうになりました 1. 通常のnew演算子 ・クラスのサイズのメモリを割り当て ・コンストラクタを呼ぶ ・deleteで解放する 2. operator new ・単に生のメモリを割り当てるだけ。コンストラクタは呼ばない ・解放する時はoperator delete ※malloc()みたいなモノ? 3. クラスでオーバーロードした operator new ・1で呼ばれる deleteで解放する 4. placement new ・既に確保してあるメモリブロック(共有メモリとか)上にインスタンスを作成する ・デストラクタは明示的に呼ぶ必要がある ・メモリの解放はメモリ獲得時の方法に依存する の四種類という認識でいいんでしょうか どこか詳しく解説しているサイト等あったら教えてください
>>91 解決しませんでした。gets()は例外を投げない関数である事を忘れて
いました。
>>97 istreamのメンバじゃない方のstd::getlineを使え。
>>96 そのplacement newはnewのあとにくるnew-placementが
void*型一つの場合で、デフォルトの(<new>に定義されている)
operator new (std::size_t, void*)かこれと同じような実装の
operator new(std::size_t, void*)を使用する場合の話。
>>96 4のplacement newを実現する方法が2と3のoperator new。
operator newは関数呼び出しの形式で使うとコンストラクタは呼ばれないが、演算子として使えばコンストラクタは呼ばれる。
operator deleteをオーバーロードすれば、そのoperator deleteを(演算子として)使うことによりデストラクタも呼ばれる。
101 :
96 :2005/04/21(木) 22:12:32
>>99 >>100 むう。難しい
関数として呼ぶ時と演算子として呼ぶ時で動作が違うという事ですか
かしこさが1あがった気がします
>>101 平たく言うと演算子のnewは
1 適切なoperator newでメモリを確保
2 確保したメモリにオブジェクトを作る
ということをしている。
>>96 の4でいうplacement newは1のステップを
渡されたポインタをそのまま返すという空の動作にすることで、
メモリ確保をせずオブジェクトの生成だけを行っている。
103 :
デフォルトの名無しさん :2005/04/21(木) 22:30:35
Visual C++6.0 を使って参考書みながら勉強してるんですけど、 二項フレンド演算子関数の所で内部コンパイルエラーとなってしまいます。 friend coord operator+(coord ob1, int i); 単項フレンド演算子関数だと平気なのですが、原因わかる方いませんか? friend coord operator++(coord &ob);
二項演算子をメンバ関数にしちゃってるとか つうかエラーメッセージを書こうよ
105 :
103 :2005/04/21(木) 22:41:32
class coord { int x, y; // 座標値 public: coord() { x=0; y=0; } coord(int i, int j) { x=i; y=j; } void get_xy(int &i, int &j) { i=x; j=y; } friend coord operator+(coord ob1, int i); friend coord operator+(int i, coord ob1); }; // ob+intのオーバーロード coord operator+(coord ob1, int i) { coord temp; temp.x = ob1.x + i; temp.y = ob1.y + i; return temp; } \StudyCPP.cpp(11) : fatal error C1001: 内部コンパイラ エラー (コンパイラ ファイル 'msc1.cpp', 行番号 1786) Visual C++ のサポート情報 コマンドを選択してください ヘルプ メニュー、 またはサポート情報のヘルプ ファイルを参照してください cl.exe の実行エラー となってしまいます。ソースは独習C++付属CDからのコピペなんで間違ってはないと思うのですが。
friend の二項演算子はクラスのメンバにできなかったと思うけど。 それより内部エラーは6.0の作りが悪い。
107 :
103 :2005/04/21(木) 23:10:17
そうなんですか。 となるとが左側に定数がくるような演算 temp = 10+ob; が出来なくなるみたいなんですがしょうがないのかな
普通の関数をfriendに
109 :
_(._.)_ :2005/04/21(木) 23:16:29
教えてください。 コンパイル中 ntddndis.hのtypedef ULONG NDIS_OID, *PNDIS_OID; のところで NtDDNdis.h(78): error C2146: 構文エラー : ';' が、識別子 'NDIS_OID' の前に必要です。 NtDDNdis.h(78): error C2501: 'NDIS_OID' : 識別名を宣言するのに、型が指定されていません。 NtDDNdis.h(78): error C2501: 'PNDIS_OID' : 識別名を宣言するのに、型が指定されていません。 ... というエラーがでます。なぜでしょうか?
110 :
デフォルトの名無しさん :2005/04/21(木) 23:16:35
質問です。環境は XP、VC++6.0 です。 ファイルのサイズを取得する方法はないでしょうか。 具体的には、 FILE* fp; fp.fopen("hogehoge.dat", "r"); として、 long size = fp.GetFileSize(); のように行ないたいです。 よろしくお願いします。
>>110 > fp.fopen("hogehoge.dat", "r");
これがまず無理。
fp.fseek(SEEK_END); って何のクラスだこれ
113 :
デフォルトの名無しさん :2005/04/21(木) 23:23:49
>>111 ご指摘ありがとうございます。
fp = fopen("hogehoge.txt", "r");
long size = GetFileSize(fp);
に訂正します。
>>109 windows.hをインクルードしてないからじゃないか?
115 :
_(._.)_ :2005/04/21(木) 23:26:13
>>114 ありがとうございます。コンパイルとおりました。
>>113 GetFileSize((HANDLE)_get_osfhandle(_fileno(fp)), NULL)
117 :
103 :2005/04/21(木) 23:28:26
119 :
デフォルトの名無しさん :2005/04/21(木) 23:29:16
>>112 もしかすると fseek は、ポインタ位置の増分を返してくれるのですか?
ありがとうございました、さっそく使用してみます。
>>116 こちらの方も検討してみます。
ありがとうございます。
>>107 手元のVC6(SP6)だとすんなり通ったよ
おまえら、ここは標準C++のスレだぞ 非標準ライブラリの話はスレ違い。 ほどほどにしろ。
122 :
103 :2005/04/22(金) 00:07:01
>>118 ,120
ありがとう。SP6にしたらコンパイルできました。
VC6は糞。窓から投げ捨てろ。
領事館の窓へ投げつけろ
125 :
北京市 :2005/04/22(金) 11:44:10
本を読んでいたら、「仮想基底クラス」「非仮想基底クラス」 などという言葉が出てきたのですが、仮想基底クラスとは どういうクラスを指すのですか? virtualなメンバ関数のみのクラスってこと?
ダライアス継承でググれ
129 :
126 :2005/04/22(金) 23:22:58
ググっても仮想基底クラスという言葉を当たり前のように使ってる とこしか・・・ orz
>>129 ダイアモンド継承した時に、親の親クラスのインスタンスを一つに絞るおまじない
とでも覚えておくとよい。それ以外は、速度が遅くなるなどデメリットばかり。
ダイアモンド継承がわかってれば質問しないだろ Aから継承したB Aから継承したC BとCから継承したD ↑をダイアモンド継承という
132 :
氷河 :2005/04/22(金) 23:45:08
ダイヤモンドッ ダストォォォーーー
133 :
126 :2005/04/22(金) 23:45:51
う〜む、するってぇと、ダイアモンド継承するときに 親の親クラスがその仮想基底クラスじゃないとなると ダイアモンド継承したクラスには、Aのインスタンスが2つ あるってことか。じゃ、あいまいさが出てくるの?
>>133 コンパイルして実験すればすぐわかる〜
struct A {
int x;
};
struct B : public A {
};
struct C : public A {
};
struct D : public B, public C {
D() {
std::cout << x << std::endl; // B::xなのかC::xなのか?
}
};
135 :
126 :2005/04/23(土) 00:46:52
やはりxへのアクセスはあいまいっすね
>>134 の場合で、BだけがAを仮想基底クラスとして継承しても
意味ないんですよね?
>>136 聞く前に実験するなり調べるなりしろよ。
編み物?
>>136 今だけ教えてあげよう。BだけがAを仮想基底クラスとして継承した場合、
Cから見てAのint xは仮想基底とはならず、やはりDで曖昧さが生じてしまう。
仮想基底の仕組みは、ポインタによく似ている。
詳しくはInside The C++ Object Modelの第3章当たりを読んでみて欲しい。
142 :
136 :2005/04/24(日) 09:11:24
>>140 ありがとうございます。
どちらも仮想基底としなかった場合と同じようにあいまいになるようですが
内部的にはちょっと違いがあるってことですかね。
>>138 「多重継承は犯罪です」スレを思い出したよ。
145 :
デフォルトの名無しさん :2005/04/25(月) 12:59:27
146 :
age :2005/04/25(月) 13:36:31
コンパイルタイムのチューリング完全性が分かったとき 毛が増えたらしい
C++の重要性っていっても、はたしてこの言語を使いこなせる奴が どれだけ出てくるのかって問題もあるんじゃ・・・。 次の標準化で少しは光が見えてくるのかしら。
C++が出て何年たったの?いまさら重要性って言われてもねぇ。
年の問題じゃないだろ。
だらだらやってるのが問題だろ。
禿げているのが一番の問題。
154 :
sage :2005/04/26(火) 11:38:22
ちょっと気になったので、誰か教えて。 C++では、標準Cライブラリの識別子(マクロを除く)は名前空間std内に宣言/定義されるよね。 でもerrnoはマクロと識別子のどちらであるか規定されないってあるんだけど。 それって、単にerrnoって書くべきか、std::errnoって書くべきか、処理系よって異なるってこと? 参照してる情報が間違ってるのかしらん。 stdoutとかも良くわからん…
sage間違えた。。鬱だ。。
17.4.1.2 - Headers [lib.headers] -5- Names which are defined as macros in C shall be defined as macros in the C++ Standard Library, even if C grants license for implementation as functions. [Note: the names defined as macros in C include the following: assert, errno, offsetof, setjmp, va_arg, va_end, and va_start.--- end note] だそうだ
訳:Cでマクロとして定義されてる名前はC++でもマクロなんだよ!
訳(追加):Cでは関数として実装しても良いヤツもC++ではマクロなんだよ!
17.4.1.2 ヘッダ -5 たとえCが処理系に対して関数として実装する許可を与えていても、Cにおいて マクロとして定義されている名前はC++標準ライブラリにおいてもマクロとして 定義されなければならない。 [注釈:Cにおいてマクロとして定義されている名前には次のものが含まれる: assert、errno、offsetof、setjmp、va_arg、va_end、そしてva_start。--- 注釈終]
160 :
154 :2005/04/26(火) 21:51:18
おお、なるほどなるほど。 疑問が解けました。 ありがとです。
VC++だとシングルスレッドの時だけstd名前空間にもあるというおかしなことになってるな boost::compatibilityなんかはほんとに.hをincludeしてるだけだ。男気がある
厳しく std 付けていこうとすると、どれがマクロなのか把握しないといけないし、 std::FILE とか禿しくキモい記述になったり、 setjmp がマクロだから std 無しで、 longjmp は関数だから std 付けて、とか、 正直やってらんない。
正直、俺も、(規約で定められてなければ)C標準のものは .hをincludeして、std付けないで使ってる。 そのやり方が非推奨だと知っていても。
using namespace std; 「標準」 のものに名前空間なんかいらないと思うんだけどな
後から標準ライブラリを増やすためだよ。 まぁ、結局unorderd_mapみたいになんだけどな。
VC++8 には iostream.h は存在しない
そんなおまいらに The C++ Standard Library Active Issue のお知らせですよ。
ttp://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#456 456. Traditional C header files are overspecified
Status: OPEN
"We should accept the fact that we made a serious mistake and rectify it, however belatedly, by explicitly allowing either of the two schemes for declaring C names in headers. "
「我々は深刻なミスを犯した事実を認め、2つのスキーマの両方を明示的に認めることによって、たとえ手遅れだとしても、これを修正するべきである。」
168 :
デフォルトの名無しさん :2005/04/27(水) 02:34:45
#include <cstdio> struct A { virtual char const* f() { return "A"; } }; struct B { virtual char const* f() { return "B"; } }; struct C : A, B { char const* f() { return "C"; } }; int main() { C c; A& a = c; std::puts( a.f() ); B& b = c; std::puts( b.f() ); return 0; } このソースを cygwin g++ 3.4.1 でコンパイルして実行すると、 "C" が2つ表示されたんですが、C::f() の定義ひとつで、 A::f() と B::f() の両方が同時にオーバーライドされたことになってるんでしょうか? エラーになるか、どちらか片方だけオーバーライドされると思っていたのに。
169 :
168 :2005/04/27(水) 02:38:59
↑のソースについて、追加で相談です。 A::f() と B::f() のそれぞれに C で別々の実装を与えるような オーバーライドを行いたい場合はどうしたらいいんでしょうか?
>>168 違う。CはA、Bのprivate継承なので、オーバライドになってない。
171 :
168 :2005/04/27(水) 03:00:24
>>170 C は struct で宣言しているので、継承は public です。
class で宣言して継承が private になっていたとしても、
オーバーライドになるかならないかに影響はありません。
172 :
168 :2005/04/27(水) 03:04:23
>>167 もう手遅れだけどな!
C++のライブラリ設計ってよく考えると結構キモス
#include <cstdio> struct A { virtual char const* f() { return "A"; } }; struct B { virtual char const* f() { return "B"; } }; struct C : A, B { char const* f() { return "C"; } }; int main() { C c; A& a = c; std::puts(a.f()); B& b = c; std::puts(a.f()); std::puts(a.A::f()); std::puts(b.B::f()); return 0; }
176 :
デフォルトの名無しさん :2005/04/27(水) 11:26:44
プログラム自体に意味はないのですが、疑問があるので質問します。 個数を0で、newすると、メモリが確保されるのですが、これはなぜでしょうか? この例の場合、char 1つ分のメモリが確保されるのでしょうか? そもそも、0でnewすることが間違っているとは思うのですが。 ガイシュツだったら、すいません。 int main (int argc, char **argv) { char *p = NULL; p = new char[0]; printf ("%d\n", p); delete [] p; exit (EXIT_SUCCESS); }
>>176 char 1 つ分のメモリは確保されない。
確保されるとみなしてアクセスすると違反や領域破壊が起こる可能性がある。
処理系の実装にもよるが、一般に new char[0]; で返される領域の直前あたりに
メモリ管理情報のための領域が取られていたりするので、[0] でも使用メモリは
%>FOXE瘧ア増える。
178 :
デフォルトの名無しさん :2005/04/27(水) 11:47:38
>>177 %>FOXE瘧ア増える。
ってなってるんだが俺だけ?
operator new でサイズが 0 の時は サイズを 1 にして確保するように規格で 決まってなかったっけ?
>>180 #include <iostream>
class A
{
public:
A() { std::cout << "Hello, world!" << std::endl; }
};
int main(void)
{
A *a = new A[0];
delete[] a;
return 0;
}
"Hello, world!" が表示されるというのか?
コンストラクタを呼び出すのは operator newではなくてnew演算子だよ。
あ、サイズが0で呼び出された時に確保される領域のサイズが1かどうかは知らね。 NULLでないこと、operator deleteを呼び出しても安全なこと、 このくらいしか決まってなかった気がするけど。
new A[0] だけを例外的に扱うのは、コンパイラの実装の際に面倒だから、 こういう処理にしていると、どっかで禿が書いていたような気が……
185 :
デフォルトの名無しさん :2005/04/27(水) 15:42:14
>>180 サイズ1っていっても、operator newからは型がわからんだろ。
1バイト?
>>180 5.3.4-7
When the value of the expression in a direct-new-declarator
is zero, the allocation function is called to allocate an array
with no elements.
189 :
デフォルトの名無しさん :2005/04/27(水) 23:31:41
メモリブロックをクラスのコンストラクタで初期化したい場合、 p = new char[sizeof(Hoge)]; *p = Hoge(100); このようにした場合一時オブジェクトのデストラクタも呼ばれてしまい、 パフォーマンス的にどうかなと思います。 そこで、 p->Point(100); こんな感じでデストラクタのようにコンストラクタが呼べればいいのですがダメみたいです。 明示的にコンストラクタを呼ぶにはどうしたら良いのでしょうか?
明示的にコンストラクタは呼べない operator newを使うとか
p->Point::Point(); p->Point::~Point();
>>189 190,191 はスルーしてるが、「メモリブロック」って何のこと言ってんの?
その例だけ見ると、 p = new Hoge(100) で何も問題ないように見えるんだが。
194 :
191 :2005/04/28(木) 00:19:11
俺は、任意のメモリブロック上にオブジェクトを構築したい、と解釈したんだがどうなんだろうな? あと、一応突っ込んどくが >*p = Hoge(100); >このようにした場合一時オブジェクトのデストラクタも呼ばれてしまい、 >パフォーマンス的にどうかなと思います。 パフォーマンス以前に構築されてないオブジェクトに対し代入するのはだめよ。
195 :
デフォルトの名無しさん :2005/04/28(木) 00:31:30
>> 190-192
placement newでも、
p->Point::Point(); でも確保済みのメモリブロックを初期化できるみたいですが、
この二つにビット的な違いはあるんでしょうか?
>>193 何らかのライブラリが返したメモリ領域とでも言えばよいでしょうか?
直接newで確保出来ない場合などです。
p->Point::Point() こんなのコンパイルとおるのか?どのコンパイラ使ってんの?
>>194 構築されてないオブジェクトとはどのような意味でしょうか…?
>>196 察して頂けてると思いますが書き間違えで本来は
p->Hoge::Hoge();
です。
ええと VC++7.1です。
この呼び出し方は一般的に通用しない方法なんですかね。
>>198 無い無い。VC++に騙されてる。忘れろ。
コンストラクタの直接呼び出しは禁止されてたような・・・
>>197 必要なメモリ領域があるだけじゃだめで、コンストラクタで構築されて初めて使える。
>>199 VC++独自の解釈なんですね。
今回の事例では便利なんですがこれが普通だと理解してしまうのはちと危険ですかね。
placement newで実装してみます。
>>200 , 201
言及ありがとうございました。
203 :
デフォルトの名無しさん :2005/04/28(木) 13:27:23
ClassA 内に ClassB を持たせようと思い、下記のように書いたのですが、 error C2079: 'ClassA::classB' が 未定義の class 'ClassB' で使用しています。 というエラーメッセージが出てしまいます。 ClassA 内で ClassB をメンバ変数として持たせる方法を教えて下さい。 お願いいたします。 // クラスのプロトタイプ宣言 class ClassB; // クラスA class ClassA { public: ClassB classB; }; // クラスB class ClassB { };
>>203 ClassBをClassAの前に持ってくる。
205 :
203 :2005/04/28(木) 18:45:14
>>204 返信ありがとうございます。
204さんの仰る方法で解決することができたのですが、またすぐにつまずいてしまいました。
ClassA から ClassB のメソッドを呼び出し。
ClassB から ClassA のメソッドを呼び出すと
error C2027: 認識できない型 'ClassA' が使われています。
error C2227: '->Method2' : 左側がクラス、構造体、共用体へのポインタではありません。
というエラーメッセージが出てしまいコンパイルできませんでした。
具体的なコードは下記のとおりです。
// クラスのプロトタイプ宣言
class ClassA;
class ClassB;
// クラスB
class ClassB {
public:
ClassA* pClassA;
void Method1() { pClassA->Method2(); };
void Method2() { };
};
// クラスA
class ClassA {
public:
ClassB* pClassB;
void Method1() { pClassB->Method2(); };
void Method2() { };
};
>>205 B::Method1()の定義をClassAの宣言の後に書く。
あるクラスを使う場合、そのクラスの完全な宣言が必要になる。
コンパイラはファイルの先頭から順に解釈していく。
new演算子を使い終了時にリークしていた時、 _CrtSetDbgFlagで正しく行番号をアウトプットに吐かせるには どうしたら良いでしょうか マクロで対応させれたと思うのですが、忘れてしまいまして、、。 宜しくお願いします (´・ω・`)
VC++スレの人が教えてくれるかと
209 :
203 :2005/04/28(木) 20:57:07
>>206 ありがとうございます。
おかげさまで解決できました。
210 :
207 :2005/04/28(木) 21:30:19
スレ違いでしたか、すみません
211 :
デフォルトの名無しさん :2005/04/30(土) 02:09:25
あんまり知ってる人いないかもしれないけども、もしいたら教えてください。 アンドリュー・コーニグのC++再考(新装版)の話なんだけど、 第八章で式をつくる(そして計算する)プログラムつくるよね? そんとき、コンストラクタの引数で直接Exprを渡してるのはなんで? const Expr&で十分、というかその方がいいのでは? たいして違わないと言われればそれまでだけど・・
>>211 Unary_Node、Binary_Nodeで引数へのポインタを取っていて、
それがconstじゃないからまずいんでしょ。
bool checkFrag(){ return (frag & 0x40); } こんな感じのフラグチェック用メンバ関数を作りたいのですが、 「warning C4800: 'int' : ブール値を 'true' または 'false' に強制的に設定します」 という警告が出てしまいます。 boolでキャストしても駄目で…返値をintにすれば大丈夫なのですがその前に質問させてください。 bool返値のまま、警告を出さずに済むような方法は無いでしょうか。
C4800 のヘルプを見ること。
お恥ずかしい…ありがとうございました
>>211 const Expr& だと、 std::auto_ptr は渡せない。
とかそういう話が出てくるからじゃないかな?
宣言と定義の違いなんですが class A; // クラスAの宣言 class A // クラスAの宣言&定義 { void hoge(); // メンバ関数hogeの宣言 void foo() {} // メンバ関数fooの宣言&定義 int i; // メンバ変数の定義? }; という認識であってますか?
あってるんじゃないかな。
> int i; // メンバ変数の定義? これも宣言かつ定義。
220 :
217 :2005/04/30(土) 13:34:52
>>218-219 ありがとうございます。
宣言と定義の違いについて自信が持てるようになりました。
int i; これって宣言でもあるの? extern int i; が宣言で 前者は定義かと思っていた・・・。
223 :
222 :2005/04/30(土) 16:17:41
ごめん。わかりにくいな。 宣言はコンパイラに名前を認識させるもの。 定義は名前と同時に、その名前に具体的な実体、意味を与えるもの。 定義ではない宣言はあり得る(class A; extern int i;)が、 宣言ではない定義はあり得ない。 うーん。たいしてわかりやすくなってないかも。
>>223 hogeが名前空間のとき、
int hoge::i;
は定義だけど、宣言ではないんじゃない?
なるほど。 int i; と似た形をしたものは全部宣言なんだな。
227 :
211 :2005/04/30(土) 20:19:11
>>212 >>216 ありがとうございます。
がしかし、実はよくわかってないです。。
引数へのポインタ?auto_ptr?えっ、何!?どこ!?という感じであります。
僕の書き方がまずかったのですが、「コンストラクタの引数」というのは
Exprクラスのコンストラクタ引数のことです。
各ノードクラスのコンストラクタ引数とデータメンバの型は、Exprが正しいと思います。
・・・で、Exprがコピーされる時には、実は内部のpがコピーされ、useが変えられてるだけ、ですよね。
そうすると、このExprコンストラクタの引数は参照で十分な気が、という話でした。
同じこと繰り返してすみません(;´Д`)
皆さんのレス書き留めておいて本と一緒にじっくり読ん
できま
す…
(´・ω・`)ここでこんなこと聞いていいのかわからないがC++初心者にわかりやすく
解説している基礎本・入門本ってありませんかね?技術的なことは書いてなくてもいいのでわかればいいです。
それとC言語もやったことないのでそこのところよろ。
プログラム作ったりしたことあるのはPerl(現在停滞中)と学校であるVisual Basic(ぶっちゃけ簡単すぎて話にならry)です。
ちなみに
>>6 の見たんですがレビューみたところよさそうなのがThe C++ Programming Languageだけでレビュー見る限り初心者にはあまりむかないそうなのでorz
template 引数を float とか double にするとエラーになるのは何故? コンパイラの仕様?小数点はテンプレートで使えないの?
>template 引数を float とか double にするとエラーになるのは何故? >コンパイラの仕様?小数点はテンプレートで使えないの? んなこたーない。 ソースとエラーメッセージを晒せ。
テンプレート引数には型と整数しか渡せなかった予感。
テンプレートの引数に渡せるのは、型・整数・テンプレートのいずれか。
>>231 使えない。
ISO/IEC 14882:1998 14.3.2 Template nontype arguments -1
A template-argument for a non-type, non-template template-parameter
shall be one of:
- an integral constant-expression of integral or enumeration type; or
- the name of a nontype template-parameter; or
- the name of an object or function with external linkage, including function
templates and function template-ids but excluding nonstatic class members,
expressed as idexpression; or
- the address of an object or function with external linkage, including function
templates and function template-ids but excluding nonstatic class members,
expressed as & idexpression where the & is optional if the name refers to
a function or array; or
- a pointer to member expressed as described in 5.3.1 .
236 :
231 :2005/05/02(月) 11:36:35
だめだあ。templateを使った事もない香具師が答えるなよ。
正直テンプレートは、STLしか使った事がない。
floatはいずれ使えるようになるんだろうか あとmplなんかではテンプレートテンプレート引数は使っちゃ駄目ってことだけど 標準はどうする気なんだろう
>>238 浮動小数点はなー。
template<float> class T; に対して、
T<10.0f> と、 T<1.0f * 10> が同じ型かどうか、
なんてのが問題になる限り、無いと思うよ。
> mplなんかではテンプレートテンプレート引数は使っちゃ駄目
こちら、解説きぼん。
240 :
231 :2005/05/02(月) 19:31:05
>>236 ……
template <const double& D>
void f()
{ std::cout << D << std::endl; }
これくらいなら通るんですが、基本的にムリっぽいですね…
>239 T<0.1f * 100> なんてのはもっと危ないな。
>>238 >>239 > mplなんかではテンプレートテンプレート引数は使っちゃ駄目
MPLで言うところのメタ関数クラスに置き換わる方向性だと思うんですけれどね.
テンプレートテンプレート引数は対象とするテンプレート引数の個数を
決め打ちしないといけないので非常に使いづらいんですよ.
>>241 0.1f * 100 = 10.0f で float ってことで
×T<10>
○T<10.0f>
ってことにはならないの?
246 :
217 :2005/05/02(月) 22:43:57
0.1f * 100 == 10.0f が真になるとは限らん。
>>246 そんなことは分かっている。
それがわかったところで>244はやっぱりわからん。
ついでにその番号コテも意味がわからん。
>246 は >244 へのレスではないだろうか。
番号コテは消し忘れっス
template Float<int bunshi,int bunbo>でいけ
>>250 Float<1,2> と Float<2,4> が別々のインスタンスになってしまう件。
固定小数点でやるしかないな
>>251 約分してやれば無問題。ついでに言っとくがインスタンスの意味を取り違えてる。
問題は無理数をどうするかだ。
>>253 正しいインスタンスの意味を教えてください。
>>253 整数をベースに加減乗除とlogとexpを許した集合なら
がんばって比較できるんじゃないだろうか。
インスタンスは実体。 int a=1, b=1; と宣言した場合aとbの内容は同じでも実体(インスタンス)は別ってことになる。
>>256 型(クラス)のインスタンス(オブジェクト)と
テンプレートのインスタンス(型か関数)を混同してないか?
>>253 ,256
「インスタンス」=「C++における型のインスタンス」と思い込んでいるようだが、そうではない。
「インスタンス」はモデルに対する実体を表す一般的な名詞。
259 :
256 :2005/05/03(火) 12:04:46
クラスのインスタンスとテンプレートのインスタンスを混同してた。orz でも、この例だと素直にclass Float{ Float(double bunshi, doouble bunbo);} で欲ねーか?
>>259 それなら typedef double Float; でいいんじゃね?
もう何がしたいのかわかんなくなってるな。発端は>231だと思うが。
いままでの流れ。
・浮動小数点数をテンプレートに渡したい(
>>231 )
・そのためには等値比較が必要(
>>239 )
・等値比較可能な数値表現として、有理数の提案(
>>250 )
・等値比較可能性もコンパイル時決定性もどうでも良くなった有理数(
>>259 )
・当然の合理化(
>>260 )
これでいけ template< class IntegralSequence, int Scale > struct big_decimal { typedef IntegralSequence unscaled_value; typedef mpl::int_<Scale> scale; }; typedef big_decimal<mpl::vector_c<int,4,5,6>,2> big4p56;
gccでmakefileの依存関係を自動で出力するのありますよね[gcc -MM file.c] bccやvcでは依存関係の自動出力などはありませんか?
264 :
デフォルトの名無しさん :2005/05/06(金) 23:12:27
ふと思ったんですけどこんなことしても平気ですか? int& ref = *new int; delete &ref;
265 :
デフォルトの名無しさん :2005/05/06(金) 23:14:38
>>264 ソースを書いてビルドして自分で試すよりも、2chに書き込んで返答を待つことを選んだわけだな?
>>266 やってみてできた、ということと保証されているということは違うよ。
>>264 それだけみると、大丈夫だろう。
何を心配している?
質問です。 std::ostringstream s; ...sを使用 s.seekp(0,std::ios_base::beg);//再利用を試みたつもり。 ...再び使用。 これで一応動作しているようなのですが、問題ありませんか? 検索したら、stringstreamでstr(string(""))すると書いてあったの ですが、いまいち違いが分かりません。 (ついでに:ostringstreamとstringstreamの違いも分かりません) よろしくお願いします。
>>269 std::ios::failbitとかstd::ios::eofbitを立ててしまったら、s.clear();しとけよ。
それからstd::ostringstreamとstd::istringstreamを多重継承したのが
std::stringstreamってだけの話。当然std::ostringstreamは出力しか
できない。
それからs.str("")はバッファをクリアするおまじない。 seekp()だけだと前に出力したゴミがくっついて出てこない?
#include <iostream> #include <sstream> int main() { std::ostringstream s; s << "abcdefgh"; std::cout << s.str() << std::endl; s.seekp(0); //再利用を試みたつもり。だけどゴミが残ってる s << "def"; std::cout << s.str() << std::endl; s.str(""); s << "def"; std::cout << s.str() << std::endl; // 今度はOK }
>>270 さん
s.clear();も無条件につけとくことにします。
stringstreamも多重継承だっんたんですね。
iとかoで始まるものを見かけたら多重継承もあるかも
と考えた方が良さげですね。
>>271 さん
>>272 さん
試したらゴミ出ました。同じ長さ以上の文字列で書き換
えていたので気づきませんでした、、
納得できました。有難うございました。
274 :
デフォルトの名無しさん :2005/05/08(日) 10:39:20
ビッグエンディアンをリトルエンディアンにまたその逆の変換をする方法を教えてください
_asm { bswap eax; }
>>274 片方ができればもう片方を作る必要はない。
変換対象が単一オブジェクトなら、
template<typename _Type> static inline void endian(_Type & val) {std::reverse(reinterpret_cast<char *>(& val), reinterpret_cast<char *>(& val + 1));}
再帰を反復子に変換するアダプタってある?
>>277 定型的に変換できるとは思えないので、無いだろうな。
あんたの言ってる「再帰」がもっと具体的な何かであれば、可能性は有る。
>>276 そうだよ。
PCIバスに挿すカードやらIDE接続するドライブなんかはプラグ&プレイであってホットプラグではないだろ?
>>277 効率悪くなるけど再帰からの出力を別スレッドからキュー経由で受け取ったものを順次読むならboost使って可能かもしれない
初歩的質問ですが、オーバーロードできない演算子の中に「.*」が あるようですが、これってどういう使い方のやつですか? 普通にa.*bみたいな感じ?こんなのありましたっけ?
>>281 「メンバへのポインタ演算子」でぐぐってみ。
>>281 メンバへのポインタの参照。
本当は *a.b と書きたいのだが、意味が変わってしまうので、新しく作られた。
純粋なCの*演算子とは意味が違い、アドレスではなくてオフセットのような
物が入っている。
>282 のおかげですごく理解できた。 >283 のせいで混乱した。
285 :
281 :2005/05/09(月) 23:48:02
レスどうもです。 ぐぐってみたところ、メンバ関数のポインタから関数呼び出しする際に 使うようですね。これ以外は使い道ないですかね。
別に関数じゃなくてもいいんだが。
287 :
281 :2005/05/10(火) 00:10:53
あ、そうですね。メンバを指すポインタからメンバを参照するときですね。
288 :
デフォルトの名無しさん :2005/05/10(火) 00:32:10
http://www.open-std.org/jtc1/sc22/wg21/ News 2005-05-09: The 2005-05 mailing is available (7400 kb tar.gz, .zip 7400 kb) individual papers
News 2005-05-09: The C++ Standard Library Issues List (Revision 36) is available (.tar.bz2)
News 2005-05-09: C++ Standard Core Language Issues List (Revision 35) is available, also committee version
289 :
デフォルトの名無しさん :2005/05/10(火) 00:52:28
いきなりC++から入る場合、何かよい参考書はありませんか?
291 :
デフォルトの名無しさん :2005/05/10(火) 10:47:07
>>291 ありがとう
とりあえず、アマゾンで注文してみました
| | | | /V\ ,J /◎;;;,;,,,,ヽ _ ム::::(;;゚Д゚)::| ジー ヽツ.(ノ::::::::::.:::::.:..|) ヾソ:::::::::::::::::.:ノ ` ー U'"U'
294 :
デフォルトの名無しさん :2005/05/10(火) 14:19:43
C++のテンプレートと演算子のオーバーロードについて質問です。 template <class T> class Parent{ public: T operator = (T x){ ・・・処理・・・ return x; } } こんな感じのクラスがあり、これを他のクラスから継承して使っています。 継承クラスは「class Child : public Parent<int> {};」という感じです。 しかし、実際に「Child a ; a = 1;」などすると 「二項演算子 '=' : 型 'int' の右オペランドを扱う演算子が見つかりません (または変換できません)。」 というコンパイルエラーが出ます。 あとこの現象はイコール演算子特有なのか「+=」を使うとエラーは出ませんでした。 Childクラスにこのoperator =()を書くと正常にコンパイルできますが、継承クラスは複数あるし、 見た目的にも何だかなぁという感じなのでそれ以外の方法で解決法があれば教えて欲しいです。 環境は WindowsXP SP2 + VS.NET2003 Academicです。 よろしくお願いします。
>>294 operator=だけは継承されない、と決められてた希ガス。
>「二項演算子 '=' : 型 'int' の右オペランドを扱う演算子が見つかりません (または変換できません)。」 そりゃそうだ
297 :
デフォルトの名無しさん :2005/05/10(火) 14:24:19
えぇ!?そうなんですか;;; ごっつい初歩的な質問すみませんでした・・・。
>>294 using Parent<int>::opereator=;
でなんとかなる。
>>295 へー。
299 :
294 :2005/05/10(火) 14:37:56
>> 298 なるほど・・・試してみましたが、ちゃんとできました。 これなら変更とかでも対応しやすそうなので充分です。 ありがとうございました!
operator=が自身の参照を返さないのは ちょっとキムチ悪いかも・・・
>>294 デフォルトの(自動生成される)
Child::operator= があるので、
Parent<int>::operator= は隠される。
コンストラクタもコピーコンストラクタもfriendも継承されないぞ。
>>302 >コンストラクタ
派生クラスから基底クラスのコンストラクタにはアクセスできるわけだし
継承されないっていうのは違うのでは?外から呼ぶ方法がないだけで。
そもそも関数が継承されるってどういう意味なんでしょう?
この辺は可視性やアクセス権限の問題な気がします。
>>303 それを言うならoperator=も呼べる。
305 :
303 :2005/05/10(火) 21:45:34
>>304 はい、呼べますよ。それが何か?
>>301 が言っているように、オーバーロード解決のときに
Parent::operator= が考慮されないだけで。
>>305 そういうのを「継承されない」って言うんだろうが( ゚Д゚)ゴルァ!!
307 :
303 :2005/05/10(火) 21:57:15
>>306 うーん、そうなんですかね。
関数を継承するってピンと来ないんですけど。
ヒマなんで規格書でも読んでみます。
>>306 どうでもいいが、それだとprivate継承はどうなるんだ?
つまり隠蔽されるわけか。
つまり、private継承はオブジェクトの継承ではなくて実装手段の継承だね。
>>311 なにが「つまり」だ?だれもそんな話してないぞ。
つまり、ぬるぽか。
コンストラクタ、コピーコンストラクタ、代入演算子、friend属性は 「継承されない」と書いているC++本多いね。糞、今まで騙されて いたのか。
まあね、クラスの外から見えないからって継承されてないわけじゃない
>>315 friend属性は「継承されない」で正しい。
printf とかのC標準関数が cstdio をインクルードしても std 名前空間とグローバルの両方にあるんだけど、 これって規格的にはOKなの? (VC .NET 2003)
つまり、sex friend属性は継承されないということですね
実際、継承とかガンガン使ってるんですか? 渡しなんかは、明に継承なんてほとんど使ったこと無いです。 単純に、外に見えるようにpublic、外に出さないようにprivate、 ぐらいの感覚でしか使ってません。protectedの使う場面は無し。 まあ何と言いますか、変数管理のしやすさ程度に使ってるって感じです。 それでもCよりC++のほうが、classを使えたり、機能的にCより上なので、 C++のほうがいいかな、とは思ってます。 (というか、C++使うのは必然的なんですけどね。)。
>>321 継承もそれなりに使っている。
話がややこしくなるからMFCは置いておくとして、ログファイルや設定ファイルなんかは仕様が似通うので
基本クラスを作っておいてそれを派生して使うことがしばしば。
この場合、コンストラクタをprotectedにして派生クラスでしか使えないようにしている。
後は、例えば読み込み関数は仮想化してフォーマットの違いに対応するくらいかな。
323 :
322 :2005/05/13(金) 01:59:06
>>322 いかん、冒頭に「私は」が抜けた。
まぁ、EffectiveC++でも読んでみるといいかも。
例外を返すべきか、エラーコードを返すべきか悩んでいます。 画像を読み込む関数なんですが、例外を返すようにすると try { loadTexture("a.jpg"); loadTexture("b.jpg"); loadTexture("c.jpg"); loadTexture("d.jpg"); catch (hoge) {} と複数の画像を一気に読むときに便利なのですが、 try { loadTexture("a.jpg"); } catch (hoge) { try { loadTextuer("hoge/a.jpg"); } } なように、最初に指定したファイルが読み込めなかった場合に違うところから 探すようにするときに不便になってしまいます。 何かいい方法はありませんでしょうか?
>>824 ちょっと考えてこんなん出ました。
loadTexture_fuzzy(name)
{
paths_t paths = {"hoge/"}
paths_t::iterator i = paths.begin();
path = "";
for(;;)
{
try
{
loadTexture(path+name);
return;
}
catch(hoge)
{
if(i==paths.end()) { throw; }
else { path = *i; ++i; continue; }
}
}
}
try {
loadTexture_fuzzy("a.jpg");
loadTexture_fuzzy("b.jpg");
loadTexture_fuzzy("c.jpg");
loadTexture_fuzzy("d.jpg");
catch (hoge) {
>>322 それ、いいすね。良い事聞きました。
そういう使い方っていいなーって思いました。
私もやってみようっと。ありがとございました。
virtual継承されたくないクラスがあるのですが、 基底クラスからそれを禁止する方法ってないものでしょうか。 C言語スレに書き込んでしまった…。
>>327 sealedがC++にあればなあ・・・・・
デストラクタをprotectedにするとかは?
だめだ、C++で継承を禁止するスマートな方法はないや。 コンストラクタをprivateにするとか(そうするってーと基底クラスの生成方法が 限定されてしまうし)、デストラクタをvirtualにしない事で、相手が気づいて くれるのを期待するとか、その程度しか思いつかない。
enemyのいないfriendワールド万歳
>>328 protected なデストラクタは継承を禁止するテクニックではなく
継承した際に、基底クラスからの delete を防ぐテクニック。
あと、
>>327 は virtual 継承の話をしていると思うのだが。
C++では、通常の継承も、virtual継承でも、強制的に禁止する手段は ないのではないかと思う。
333 :
327 :2005/05/13(金) 15:31:24
virtual継承するな、のコメントを目立つように工夫しました… orz。 既にやられちゃってる部分は、担当を蹴り飛ばしてきます。 いや、自分が悪いのか。
virtual継承って事は、ダイヤモンド継承でも行いそうになってるのか? それに実行速度が落ちるしなあ・・・・
335 :
デフォルトの名無しさん :2005/05/13(金) 19:58:10
>>335 nonderivable_baseを非仮想基本クラスにすると通っちゃうのはなぜだろう。
つか仮想基本クラスだとBをエラーにできる理由がわからんorz
>>337 コピー不可じゃなくて継承不可の話してるんだよ?
だめだ。昨晩飲み過ぎてから、馬鹿になった。 しばらく書き込み控えよう・・・・脳細胞が破壊された模様。
>>335 > friend typename identity<T>::type;
ん、これ良いのか?
初歩的な質問で申し訳ないですが、聞いてください。 class A; class B; を協調させて使うクラスCを作りました。 class C { private: A &a; B &b; C( A &a_, B &b_ ) : a( a_ ), b( b_ ) {} ... }; 質問1 クラスのメンバに参照持たせて不都合があるでしょうか?ポインタ置いたほうがいいですか? 質問2 上記のようにしたのは、aやbの動作をいじるためにそれぞれのメソッドを呼びたいからです。 class Cは、 class C { private: A a; B b; public: A& getA( void ) { return a; } B& getB( void ) { return b; } }; publicに晒すのは良くないらしいので、これでも良いのですがどのようにしたらいいと思われますか?
>>341 それは包含(composition)という手法で、has-a関係を表すのによく使われる。
ポインタにするか参照にするかは、実行途中で包含しているクラスの実体を
切り替えたいかどうかで決めればよい。どちらにしても仮想関数はちゃんと動く。
それから、実体の参照を返すくらいだったら、包含にせず、外で実体を持った
方が良い。あくまでもprivateで外に見せない事を前提にメンバにしているのだ
から、外から操作できたら意味的に本末転倒だ。
>>341 >質問1
問題ない。
>質問2
メンバ変数をpublicにしない方が良いと言われるのは、
公開した場合、包含クラス(この場合C)が被包含クラス(A, B)を使って
実装されているという事実が、包含クラスのインタフェースに表れるのを嫌っての事。
従って、この点では、メンバ変数の参照を返すメンバ関数を公開するのは、
メンバをpublicに置くのと大して変わらない。
>>342 >>343 お返事ありがとうございます。
この場合、Cにaやbを持たせず、
C::func( A &a, B &b )として外から引数で与えようかとも悩みました。
いちいち引数に指定するのが面倒なのでメンバに置いたのですが…
C++は悩みが尽きません。
>>345 そういう事なら、包含だとは思わず、publicメンバで持ってしまえばよい。
ま、しかし、そういう設計をする事はあまりないので、他人が貴方の作った
クラスを見てどう思うか、それを意識しないで済むのなら自由なんですが。
クラスCに関連するクラスAとクラスBのローカルな実体を持って、なおかつ
それを外部に公開するとなると、CがA及びBに意味的に縛られている限り、
外部からAやBを自由にされてしまうと、その都度Cのコンディションを把握
しなければならないようになり、余計な心配が増えるだけ。
かと言って継承を使うとなると、AとBからの多重継承になり、これまた
頭が痛いですね。
私だったらAとBはprivateもしくはprotectedにし、細かいアクセサを付けて 外部からの操作を徹底的に制限する方向に行きます。
例えばAやBが座標値のような汎用のクラスなら、 const参照を返すようには作るなぁ。 これなら外部から変更される心配が大幅に減る。
>>346-348 お返事ありがとうございます。
クラスを協調させるクラスは必要だと思うので、すっきりした方法があると思うのですが…
AやBの設計が間違っているのかなぁ。手間はかかっても
>>347 さんの設計がいいのかなぁ。
>>349 CがAやBの内容を見て動くのならば、AとBでCをfriendとして宣言したら
どうだろうか?これもあまり勧められた方法ではないけど、一応役目は
果たすんじゃない?
それか、これはデザパタの話になってしまうけど、Strategyパターンを起用する手もある。 サブクラスがいたずらに増えるのを防止して、CからAやBを自由に切り替えて使える ように出来る。
まともに議論するには情報足りなすぎ。 想像であーだこーだ言っててもしょうがない。
>>352 まあな。C++はいくら自由度が高いと言っても、ある程度ルールに乗っ取った
クラス階層にしないと、Cのポインタの使いすぎと同じで可読性が著しく下がる。
当然メンテナンス性も大幅に低下する。
継承を使うべきでない所に無理に継承を使ったり、カプセル化の大原則を
無視して意味不明なプログラムを作る香具師大杉。
354 :
デフォルトの名無しさん :2005/05/15(日) 13:23:43
C++ の iostream は実装が重いから使わないほうがいい、って本当ですか?
>>354 現状、 cstdio を使って実装されていることがほとんどなので、
cstdio に比べて重い実装が多いのは本当。
使わないほうがいいかどうかは、使う側で判断するべし。
iostream の遅さがプログラムの動作に致命的な影響を与えるなら使わない (使えない) そうでないならご自由に。
クラスのメンバ関数から、自分自身をdeleteするようなことは できるのでしょうか?
>>357 規格では明確になっていないと思うが、現実問題としてできるし、
多用されている。ただし delete した後はメンバに触らないように
注意ね(即 return するのがお奨め)。
VS.NET2003で、付属の標準STLでのことですが、 typedef struct { int x, y; }POS; const int ARRAY = 5; std::map< string, POS[ARRAY] > BBBmap; POS a[ARRAY]; // BBBmap["HOGE"] = a;// 配列operator= 未定義なので× // BBBmap["HOGE"][2] = a[2];// intからPOS[5]に変換できません て出るので std::map< string, POS > BBBmap[ARRAY]; を使ってるんですが、これは前者のmapをスムーズに使いたきゃ 配列operator 定義しろやゴルァってことでしょうか。
>>359 std::map< string, POS[ARRAY] > BBBmap;
を、
std::map< std::string, std::vector<POS> > BBBmap;
にしろ。そしてSTLスレに行け。
361 :
357 :2005/05/15(日) 18:55:35
>>358 レスどうもです。
するってえと、
delete *this;
こんな感じですかね。
362 :
357 :2005/05/15(日) 18:59:18
あ、違うな。 delete this; でいいのかな?
363 :
359 :2005/05/15(日) 19:08:23
360さん、どうもです、そしてすみません。 以後気をつけます。
調べてみたけど、コンテナの要素に配列を入れるのは、規格外のようだね。 §23.1.3 The type of objects stored in these components must meet the requirements of CopyConstructible types (lib.copyconstructible), and the additional requirements of Assignable types.
367 :
341 :2005/05/16(月) 00:19:48
template< typename IMP1_, typename IMP2_ > class Driver { public: IMP1_ &imp1; IMP2_ &imp2; Driver ( IMP1_ &imp1_, IMP2_ &imp2_ ); void shori() { ... imp1.shori( imp2 ); //処理を委譲 ... } }; template< typename POLICY1, typename POLICY2 > class IMP1 { private: MEM1 mem1; MEM2 mem2; public: POLICY1 t1; POLICY2 t2; template< typename X > void shori( X &x ) { x, mem1, mem2, t1, t2 を使って処理; } }; (続く)
368 :
341 :2005/05/16(月) 00:20:38
class IMP2; int main( int argc, char *argv[] ) { IMP1< POLICY1, POLICY2 > imp1; IMP2 imp2; Driver< IMP2, IMP1< POLICY1, POLICY2 > > driver( imp2, imp1 ); ... driver.shori(); ... } IMP2, POLICY1, POLICY2 は 取り替え可能としたい。 IMP1を見て頂いたらわかると思いますが、publicにPOLICY1,POLICY2をおいています。 たまに、imp1.t1.hoge(), imp1.t2.hoge()等とメソッドを呼んで動きを調整したいのです。この場合、IMP1に細かくアクセサを作っていくとIMP1がPOLICYの数だけできて嫌な感じになると予想して躊躇しているところです。 何かいい方法はないものでしょうか? (続く)
369 :
341 :2005/05/16(月) 00:25:16
と整理していましたら道が見えてきた気もします(まだ巧く表現できません)。
>>352 さんの仰る通り、問題を簡単にしようと情報を切りすぎていました。
申し訳ございません。
>>367-369 もしかして template 覚えたてだったりするか?
速度に対する要求がシビアなプログラムでもなければ、
template 使いすぎの悪い例に見える。
372 :
341 :2005/05/16(月) 00:36:08
template覚えたてです…
373 :
341 :2005/05/16(月) 00:45:16
stateパターンってこの場合に使えるんですか?
ちょっと考えてみます。
>>370 さんありがとうございます。
>>372 じゃぁ template の使いすぎに注意して考え直してみるべきじゃないかな?
もうすこしすっきりすると思うぞ。
>368 つ [Modern C++ Design] 普通にStrategy/Stateパターン使ってもいいけどね。
こやつにModern C++ Designを読ませるのは、火に油を注ぐようなものだと思うが。
下記のテストプログラムをbcc32でコンパイルした場合、 1=32,2=24,3=4 になってしまうのですがこれはC++Builderのバグでしょうか? gccだと1=28,2=24,3=4になります。 #include <stdio.h> typedef struct { signed long long a, b, c; unsigned long d; } test1; typedef struct { signed long long a, b, c; } test2; typedef struct { unsigned long d; } test3; int main(void){ printf("1=%d,", sizeof(test1)); printf("2=%d,", sizeof(test2)); printf("3=%d\n", sizeof(test3)); return 0; }
その辺はコンパイラの勝手なのでバグじゃない。
ちなみにbccには"long long"という型は無い。
381 :
378 :2005/05/17(火) 08:44:59
>>379 ,380
なるほど…
ありがとうございました。
>>378 -a4スイッチつければbccでもtest1は28バイトになる。(デフォルトは-a8で8バイト境界になってる)
BohYoh.comのFAQに間違いがあるのが気になる・・・問い合わせは受け付けてないし・・・
>>383 どの間違い?柴田先生には相当傾倒している俺としては気になる。
C++ FAQ > デストラクタを明示的に呼び出すことはできますか。 > > できません。 かな。
>>386 サンクス。
あーそりゃ完全な間違いだわ。
typedef void (*testProc)(int); class testClass{ static testProc proc; public: testClass(testProc ProcAddress){ proc = ProcAddress; } static void CallProc(){ proc(0); } }; ってやるとprivate: static void (*testProc)(int)が未解決ですって出るんだけど、 どうすればいいかな
実体を用意する
>388 適当なcppファイル中に testProc testClass::proc;
"class内のstatic変数は宣言であって定義ではない"って 感じのことをcppll(だと思う)で見つけたけど、それと同じこと?
>>391 >>390 が答えを書いているが、要するにクラスのstaticメンバはクラス外で
定義しないといけんのよ。理由はわからんが、多分クラスのインスタンス
がいくら増えても、あるいはインスタンスが一つもなくても、staticメンバは
一つきり実体があるためかも。
393 :
388 :2005/05/20(金) 00:41:36
ありがとう、無事解決できた。
>>392 アドレス比較するぐらいしか思いつかんのだけど、インスタンスの実体は
(コンパイラ作る人からすれば楽そうだし)スタック(もしくはそれに類するも
の)に置いたりしてるんじゃないかな。
static変数やstaticなメンバ、グローバル変数等はひとくくりに
扱える気がする(実体ひとつだと領域が確定しているし)
・・・にしても別にclass宣言内で初期設定できるような規定?でも良かったよ
うな気もする。でもそうなってないなら従うしかないか
微妙に思えるのはローカル関数内(mainもそう分類されるのか知らん)のstatic
なクラスのインスタンスやグローバルなクラスのインスタンス。
まあでもこれだって、サイズは(コンパイラに)わかってるわけだし、初期化前
にインスタンスの領域を確保しないだけ・・・・と推測してみる。
(一回だけ構築するように関数埋め込むのかもしれん。この方がデストラクタ
呼ぶ時も分かりやすそうだ。インスタンス用に1つレジスタ裂けたらこっちが良さげ鴨)
・・・長々と空想ごめん。もう寝る。
>>394 class内で初期設定できるのはstatic const intだけだね。
しかしその理由を[C++の設計と進化]の中で探したが、見つけられなかった。
P367にはどこかに置くとしか書いてないし。探し方が足りないかもしれない。
俺も眠いから寝る。 (つ∀-)オヤスミー
396 :
デフォルトの名無しさん :2005/05/20(金) 11:25:41
基底クラスのコンストラクタをそのまま派生クラスで使いたいのですが class A{ public: A(int n); A(int n1,int n2,int n3); A(char *s); }; class B : public A{ public: B(int n) : A(n) { } B(int n1,int n2,int n3) : A(n1,n2,n3) { } B(char *s) : A(s) { } }; やっぱりこういうふうに、すべてのコンストラクタについて 定義し直さなければなりませんか? (すべてのコンストラクタをそのまま使えるようにしたい場合) コンストラクタの数が多いとめんどくさいので、 宣言を省略する(もしくはより短く表記する)方法があれば嬉しいのですが…。
>>396 class B : public A{
public:
B(A const& base) : A(base) {}
望むものとは違うかもな。
>B(int n) >B(char *s) (;`Д´)・・・・・
>>397 なるほど。暗黙の変換がされるわけですね。
引数の数が1以外だと使えませんが…。
でも引数の数が1つのことは多いので役に立ちそうです。
ありがとうございます。
>>398 例として挙げただけです。
曖昧さが生じることはあんまりないと思いますが。
map<string, hoge>とした場合、デフォのless<string>では大文字小文字が区別されますが 区別しないバージョンは標準には無いんでしょうか? 自分でちょちょいと書くしかないのかな(´・ω・`)
>>400 標準には無いよ。
でも、いろんな人が書いてるからどっかから拾ってこれるかもしれない。
ん? boost::algorithm になんかありそうだな。
402 :
デフォルトの名無しさん :2005/05/20(金) 13:09:28
プラグインの開発用に公開したいヘッダーファイルがあって、 その中にあるクラスの宣言は公開したいけど、中身は公開したくないってとき どうすればいいかな。 クラスの中に実際のしょりを書かないでソースファイル内への関数のポインタで初期化しようかと考えたけど それだとソースファイル内の関数群のtypedef宣言しなきゃいけないし、構造体でいい事になりますよね それにクラスで宣言すると、VCだと(他のソフトは使ってないからわからない)ナビが出てわかりやすいと思うんですよ。 もっとスマートな方法ってありますか
公開したくない部分をクラス化しておいて 公開しても良い部分のクラス内で↑のを使う。このクラスを公開する。 そうすれば公開したくない部分は、パブリックなメンバ関数しか見えない。
>>402 よくわからんがPImplとかそういう話?
この話題もFAQだよなー。
>>403 //----公開するヘッダ----
class A{
public:
Proc(int x){
B::bProc(x);
}
};
//----公開しないヘッダ----
class B{
public:
bProc(int x){
}
};
//----プラグイン側ソース----
A a = new A();
a.Proc(0);
こういうこと?
B::bProc(x);この文でコンパイルエラーになりそうだけど
>>406 おまいの頭には「公開しないソース」という概念は存在しないのか。
>>402 こうやるんだよ(←高圧的な物言い)
公開するヘッダ
class A {
public:
static A* CreateInstance();
virtual void Proc(int x);
};
公開しないソース
class AImpl : public A {
virtual void Proc(int x) { ... ;};
};
A* A::CreateInstance() {
return new AImpl;
};
プラグイン側ソース
A* a = A::CreateInstance();
a->Proc(0);
仮想デストラクタ忘れてた・・・
つーか、プラグインの形態にもよるがCOMとか経由せずにDLLとかでC++のクラスを公開するのは非常に面倒なんでやめとけ。 ABIがらみとかでハマりたいならとめんが。
Jana風なコーディングしてる人に聞きたいのですが、 名前空間の名前はどのようにつけていますか? NameSpace? nameSpace?
>>411 namespace jp{ namespace co{ namespace company{ namespace product{ namespace module{
} } } } }
にでもしやがれ
414 :
デフォルトの名無しさん :2005/05/20(金) 20:48:14
すいません、質問お願いしたいんですけどいいでしょうか? BorlandでC++ Compiler 5.5というのをダウンロードしたんですがこれだけでは使えないんですか? まだ初心者なものでくだらない質問ですいません。
PC自体の初心者の場合、 ・店行ってVC++.net 2003 Standardを買ってきてインストール ・Dev-C++あたりを日本語の解説見ながらインストール&日本語化 ・BCCを解説ページ読みながら自力で設定 のどれが一番簡単なんだろうな?
>>415 ・店行ってVC++.net 2003 Standardを買ってきてインストール
これが一番簡単だと思う…。
インストールして、プロジェクト作って、ソース書いて、ワンクリックでビルド。
俺、もうVC無しじゃ生きていけない。
学生ならthe Spokeね。
学生でないなら、 Borland C++Builder 6 Personalの方が安い?
あるクラス(A)の処理で別のクラス(B)を引数に持つときに Aより先にBを宣言しないとダメっぽいんだけど 関数のプロトタイプ宣言みたいに宣言だけ最初にまとめて記述ってできないのかな
class B;
>>420 それはやってみたんだけど認識できない型でコンパイルエラーなんだよね
ポインタか参照で持て
424 :
デフォルトの名無しさん :2005/05/21(土) 02:17:09
endl と \n の違いがよくわかりません。どのような状況では endl を使ったほうがいいのでしょうか?
>>424 std::endl は '\n' と std::flush をいっぺんに突っ込む。
エラーの起こる可能性の有る処理の前、
時間のかかる処理の前に出すメッセージ、
など、画面への表示を確実に完了させたいときに使う。
関数の引数として渡されたポインタ変数がdeleteできるかどうか 確かめる方法ってありますか? あるいはdelete[]じゃないとやばいかどうかとか知りたいんです。 もしくはdelete及びdelete[]できない型を渡せなくするとか。
>>426 できん。
その分、newの際にできるだけ使用するヒープ量を減らす事にしたのだから。
428 :
デフォルトの名無しさん :2005/05/21(土) 05:03:41
deleteできるかどうかも渡したらいいんじゃない?
>>428 それはdeleteした後にポインタ変数に0を入れておくなどの用心しかない。
できるだけクラスにして、デストラクタに始末させると綺麗に書けるんだけどね。
そうしたくない場合が多いからね。
430 :
426 :2005/05/21(土) 07:41:52
すみません、書き方がまずかったかもしれません。 具体的にはクラスのポインタをハッシュテーブル化することを想定した テンプレートクラスで、要素を削除したときインスタンスも一緒に削除 したいんですが、仮に以下のようにstd::mapで実装したとして template< typename keyT, class valueT > class HashContainer { typedef std::map< const keyT, valueT * const > container_t; container_t *m_container; 〜中略〜 public: void Delete(const keyT& key) { container_t::iterator result = m_container->find(key); if (result != m_container->end()) { delete (*result).second; //←■問題の箇所■ m_container->erase(result); 〜以下略〜 HashContainer< int, int > などとされて int a = 10; の &a なんかを 渡されちゃうと、問題の箇所でぶっとんじゃうのをなんとかしたいんです。 問題のある型でインスタンシエイトできなくするか、問題が無い場合だけ deleteするか、何か良い方法はないでしょうか?
>>430 変数のアドレスを渡すなとコメントに書くしかない。
ただstd::auto_ptrやboost::shared_ptrにすればnew使えという意思がソースからも読み取れるようにはなると思う。
>>430 ポインタを渡しただけなのに、その指している先を削除してしまうコンテナは実装がまずいといえる。
deleteしない、deleteする、delete[]する、の3種類の動作が分けられるスマートポインタを提供し、
さらにそれを格納するコンテナを提供するのが筋。
×実装がまずい ○設計がまずい 俺は何を言ってるんだ・・・。
すまぽ すまぽ ぬるぽ
435 :
426 :2005/05/21(土) 15:04:22
なるほど… 実体の無いインターフェース用意して
それを継承したクラスしか渡せないとかダメかな?
class IDeletable {};
として
std::map< const keyT, IDeletable * const > m_container;
みたいな
これでもスタックに確保された配列とか渡されたらダメか…
>>432 氏の方法を考えてみます
クラスがdeleteされるときに呼ばれる関数をクラスの中に組み込めますか?
ファンクタ使えばできる。 shared_ptrとかもそうしてはず。 GC使えばいいのに...
439 :
デフォルトの名無しさん :2005/05/21(土) 21:32:25
>>436 デストラクタからなにか関数を呼ぶということだと思うけど、
自身の仮想関数を呼ぶと愉快な動作をしてくれる。
>>439 デストラクタというんですね。ありがとう
自分の無知さがはずかしい
話がかみ合ってないのに情報が伝わっててワラタ
442 :
デフォルトの名無しさん :2005/05/21(土) 22:57:10
ええと。ホームページで携帯からアクセスを禁止にしたいのですがどうすればいいのか分からないんですけど・・・ どなたかお願いします。
+激しくスレ違い+
むしろなぜここに質問しようと思ったのか全く理解できないくらいスレ&板違い
445 :
デフォルトの名無しさん :2005/05/22(日) 01:44:06
メソッド内で定義したローカルクラスのポインタを返すのって、C++ の言語仕様的に やっても大丈夫なのかな・・・。 あるいは言語仕様的には OK でもちゃんとコンパイルできない処理系があるとか・・・。 とりあえず g++ ではうまくいったわけだが。 ---以下サンプルコード--- #include <iostream> struct Giko { virtual void gorua() { std::cout << "ゴルア" << std::endl; } }; struct Hoge { Giko* createGiko() { struct FusaGoko : public Giko { virtual void gorua() { std::cout << "フサフサ" << std::endl; } }; return new FusaGoko(); } }; int main() { Giko* giko = Hoge().createGiko(); giko->gorua(); delete giko; return 0; }
447 :
445 :2005/05/22(日) 01:45:40
プログラムの動作そのものには関係しないけど、FusaGoko → FusaGiko ですた・・・。
448 :
445 :2005/05/22(日) 01:48:31
449 :
デフォルトの名無しさん :2005/05/22(日) 01:50:14
Visual C++ 6.0でコンパイルをするとリンク中と表示されたままで進まないことが以上に多いんですけど、これってどうしようもないんですか?教えてください。
かつてCで書いたプログラムを、勉強+将来のGUI化に向けて、C++に書き直しています。 この中で、調べてもよくわからないところがありましたので質問させていただきます。 C言語(stdio.h)のfscanfとかfseekに相当する関数は、C++(fstream.h)ではどれにそうとするのでしょうか? また、C言語とC++との違い・対応がわかりやすいサイト・書籍がありましたらご紹介願います。 // テンプレ嫁といわれてしまいそうですが_| ̄|○ わかりにくい文章かもしれませんが、よろしくお願いします。
>>451 fscanf は各型の operator >> が対応していると言えなくも無いかな。
fseek は読み込みなら seekg だろうな。
無理に fstream を使わなければ、そのまま動くはずだけど。
あと、 fstream.h は fstream にしとけよ。
最後に、テンプレ嫁。
>>451 現在のC++ではfstream.hは存在しないから将来も何もない。
どうしてもわからなければsed::getline()でstd::stringに読み込んでから<cstdio>のstd::sscanfを使う方法もあるさ。
>C言語(stdio.h)のfscanfとかfseekに相当する関数は、C++(fstream.h)ではどれにそうとするのでしょうか? やはりここは、 C++(cstdio)のstd::fscanf()とかstd::fseek()が相当します。 と答えたくなるな。
newで返されるポインタの型をキャストするときは static_castですか?それともreinterpret_castですか? ポインタの型は論理変換でしたっけ?
operator newをオーバーロードしたいのですが、 そのオーバーロード関数内で MyClass *p; p = ????_cast<MyClass*>( new char[chunk] ); の場合は、どのキャストがベストですか?
reinterpret 以外あり得ない
staticとreinterpretと両方見かけたことがあるんですよね。 Effective C++ P.63には Airplane *newBlock = static_cast<Airplane*>(::operator new(BLOCK_SIZE * sizeof(Airplane)) ); とあるんですが、このケースは違う?
>>461 void *からT *へはstatic_castが使える。
char *からT *へは使えない。
>>462 なるへそ。
ということは
new ???
こういう書式だと、???の型のポインタが返されるけど
operator new(size_t)
この書式だと、コンパイラは型がわからないからvoid*型が
返されるってことかな?
.Netではあるクラスを初期化するときに new ClassA(a, b, new ClassB() ); といったように別のクラスを引数としてとる事がありますが これはC++だとdeleteされないからメモリリークを起こしますよね
それってClassAのデストラクタでClassBをdeleteすればいいんじゃないの?
たとえばnew Brush(new Color(255,255,255));みたいに Brush側でColorがこの後利用するかどうかって判断つかない場合もあると思うんですよ
>>466 Colorみたいなものは値渡しだからどうでもいいとして、
初期化がどうとかいう話ではなく、「GCがないから
いらなくなったら自分で delete しないとメモリリークを起こしますよね」
っていう話のような気がする。
そらC++なら当たり前だ shared_ptrでも使えば?
GCが防いでくれるのは多重開放であってメモリリークではない。
reinterpret の読み方って 「りんたぷれっと」 でいいの?
リインタプリトって読んでいる。 interpreter = インタプリタから。
リインタプリトって読んでいる。 interpreter = インタプリタから。
473 :
デフォルトの名無しさん :2005/05/23(月) 17:21:54
引数が省略可能とする時は、プロトタイプ宣言にてデフォルトを記述しますが、 引数が構造体の場合は、デフォルト値はどのように記述すれば良いのですか?
>>473 構造体にコンストラクタを設けて、デフォルト引数を一時オブジェクト作成にすればよい。
struct A
{
int x;
A(int x) : x(x) {}
};
void f(A a = A(0));
476 :
デフォルトの名無しさん :2005/05/23(月) 20:12:57
class A { }; class B : public A { }; ////////// B* x = new B(); A* y = x; // ← これは大丈夫なのに B** z = &x; A** w = z; // ← これは駄目なのはどうしてなのでしょうか?
>>476 どうして?と聞かれても、仕様だ!と答えるしかないな。
その変換を認めると、
A **w = z;
*w = new A;
// ここで*zを使う
のようなコードで、Bのつもりでアクセスした実体が実はAだった、ということがおきる。
つまり、その変換は安全じゃないから、禁止されている。
478 :
477 :2005/05/23(月) 20:27:08
// ここで**zを使う ね。
いつも思うのだが Bjarne Stroustrup これは正確にはなんと発音すればいいんだ? 俺はうまく発音できなくて禿げ禿げでごまかしてるんだが。
情報処理用語かよw
ビアルネだったのか・・・ビヤーンだと思ってた。 つか情報処理用語なのかこいつの名前は。
継承して欲しくないクラスを明確にする為に #define final_class class final_class foo { }; みたいな事するのって気色悪いですか? 用語はまあsealed_classとかでもOKなんですが デストラクタをvirtualにしないだけじゃ設計ミスみたいだし…
俺はデストラクタがvirtualでなければ継承禁止の意思表示に取るけどね マクロ使うぐらいならコメント一言入れとけば?
>>484 class foo { // 継承したら肛門童貞奪うぞ
};
((( ;゚Д゚)))ガクガクブルブル
>>486 肛門が童貞じゃないお兄さんなら継承しても平気なわけだ。
おねいさんはだめですか?
ビヤーンネ・ストローストロップが正しいのか。
それを言い出すとカナ表記しようとする段階で間違い。
イヤーネ・スカトローストリップ?
イヤーン・スカトロストリップ?
ファイル名が指定されているときはそのファイルに、 ファイル名が指定されていないときは標準出力に、 それぞれ出力したい場合: void f(const string &filename="") { ostream &fout = (filename != "") ? *(new ofstream(filename.c_str())) : cout; fout << "hello, world" << endl; if (&fout != &cout) delete(&fout); } というように書けばいいんでしょうか?
>>495 そんな感じでいいと思うよ。
俺だったらconst char *版もオーバーロードするけど。
void f(const string& str) { ofstream ofs( filename.c_str() ); f( ofs ); ] void f() { f( cout ); } void f(ostream& os) { os << "hello" << endl; }
>>497 それだったらデフォルト引数にcoutを書けばいいだけじゃねえかよ。
漏れだったらstd::stringのconst参照ではなくconst char *をとるようにするなぁ。
俺ならおとなしくこう書くかな。 void f(const string &filename) { if(filename.empty()){ ff(cout); } else{ ofstream ofs(filename.c_str()); ff(ofs); } } void ff(ostream &os) { os << "hello, world" << endl; }
static inline void ff(ostream & os = cout) {os << "hello" << endl;} static inline void f(const char * filename = NULL) {filename ? ff(ofstream(filename)) : ff();}
inline void f(std::ostream& os = std::cout) {os << "hello" << std::endl;} inline void f(const char *filename) {filename ? ff(std::ofstream(filename)) : ff();} inline void f(const std::string& str) {f(str.c_str());}
finalにしたいなら class final { class foo {}; } つうのはどうでしょう?
C++で手続き型のプログラムって普通はしないものなのか。
>>504 実装側で適当にやるのは良いと思う(というかそういう言語だと思う)が
公開するインターフェースはオブジェクト指向にして欲しい
ナポリタン
C++の関数の中の書き方(セミコロンで区切って命令を順番に書く)を手続き型というのであって、対義語は関数型もしくは論理型。 オブジェクト指向かどうか(これは設計の問題)とは関係ない。
>>511 手続きを抽象化するスタイル(要は構造化)のことを
オブジェクト指向と対比して手続き型と言うことがあると思う。
plc++3にはこの意味で出てきた。
>>511 > C++の関数の中の書き方(セミコロンで区切って命令を順番に書く)を手続き型というのであって
セミコロン云々はそりゃいくらなんでも違うだろ。
代入を順番に書き連ねて、その副作用を利用していくのが手続き型。
> オブジェクト指向かどうか(これは設計の問題)とは関係ない。
これも間違い。多くのオブジェクト指向プログラミングは、これまでのところ
手続き型言語の枠組で提案されてきてる。その理由としては、特に手続き型の
対極にあたる宣言型、そのなかでも関数型の場合は、状態を保持するオブジェ
クトとの相性があまりよろしくない。そもそもオブジェクト指向のサポートの
一切ない言語(たとえばHaskell)を使うのにオブジェクト指向で設計、などあ
り得ない。
おとなはうそつきだ
>>513 C++では区切り子にセミコロンを使っているというだけの話だろ
セミコロン必須だとはだれも思っちゃいない(お前以外は勘違いすらしない)
>>513 >代入を順番に書き連ねて、その副作用を利用していくのが手続き型。
Lispは手続き型?
>>515 > セミコロン必須だとはだれも思っちゃいない(お前以外は勘違いすらしない)
勘違いしてるのはお前だろ。511も513も「セミコロン必須」なんて話はしてない。
>>516 > Lispは手続き型?
「Lispが関数型」っていうのは「Cが関数型」っていうのと同じくらい正確。
ん?言葉の使い方が悪かったか? セミコロン必須 = 文と文を区切るためにセミコロンを使うこと と解釈してくれ
513はセミコロンに拘ってるな
520 :
デフォルトの名無しさん :2005/05/25(水) 22:23:01
virtual functionを実現するコンパイラの仕組みがよく わからなかったので教えてください。 実際のクラスの関数へのポインタをデータの中に埋め込んでおいて それを使用して関数を呼び出すというのはわかったのですが、 その関数に暗黙に渡されるインスタンスへのポインタの渡し方が よくわかりませんでした。 多重継承している場合はベースへのポインタと派生クラスの ポインタでアドレスが異なる場合がありますよね? その場合は実際に渡すアドレスをどこで変換してるんでしょうか?
>>520 thisは実際のところ、関数の引数として渡されているだけ(の実装が多い)。
>523 >520 に答えようとして途中でわからなくなったんだけど、勉強になった。サンクス。
525 :
520 :2005/05/25(水) 23:28:51
>>523 なるほど、理解できました。アドレス補正処理も同時に埋め込んでいる
んですね。
526 :
デフォルトの名無しさん :2005/05/25(水) 23:29:48
おそレスだが >485 コンストラクタを全部privateにしちまえばいいんでない。 んで、statci A& A::getInstance()とかしておくと >486 まあ、それで十分な開発体制ならいいんだけど、 現実はマーフィーの法則を超えることがあるわけで
527 :
デフォルトの名無しさん :2005/05/25(水) 23:34:54
>520 回答はすでにされているので、ほんとにあった怖いコード クラスをmemsetで丸ごと初期化してる
>513 そりゃぁ、状態を管理するオブジェクト指向と状態を持たない純関数型言語では 相性悪いだろうに……
エスケ−ブシ−ケンスはW2000では使えないようなのですが 例えば printf(”¥x1B[%d;%dH%s”,plin,pcol,str); での表示はどう直せばよいのでしょうか?
半角に直せばいいと思うよ
つーか、スレ違い。
>>529 SetConsoleCursorPosition
finallyを使うのと、単にtry・catchブロックの次に書くのとでは何が違うのでしょうか?
__finallyはMS拡張であってC++標準ではない。
例えばtryブロック内でreturnしてもfinallyが実行されるんでないっけ
newを使って二次元配列を作り初期化する方法ってどうやればいいのでしょうか? int (*a)[3] = new int a[3][3] ={ {1,2,3}, {4,5,6}, {7,8,9} } これはだめでした
finally はめちゃめちゃ欲しい。 デストラクタで処理すりゃいい話だけどそんな細かいニーズのためにクラス作ってらんない。
デストラクタじゃ代用にならないだろ。 クラスは破棄されないんだけど、エラーが発生してエラー処理、って場合に。
スマートポインタのデストラクタで代用できるだろ
エラー処理をfinallyに書いてどうする。
finallyも例外自体もスコープアウト時のガベージコレクトのないレガシー言語の機構。
finally の用途はメモリ関係に限らないんだけどね。
スパートポインタ系のラッパクラスにしてもメモリ以外にも適用できるわけだが。 Rubyみたいにファイルオブジェクト作るたびに例外ハンドラ書かされる糞言語見てるとGCが大して幸福に貢献しないことがよく分かる
>スパートポインタ >スパートポインタ >スパートポインタ
>>545 もしかしてスパートポインタも知らないのか?
ダストスパート
549 :
デフォルトの名無しさん :2005/05/26(木) 20:29:10
ものすごく初歩的な質問なんですが、 今、C++の参考書を読み終わったのですが、 クラスや関数のことについては大体分かりました。 まずは簡単な住所録をつくろうと思ってたのですが、 コマンドプロンプト上でしか動かせない状況です。 これから先はMFCやAPIを勉強していけば C++のソフトを作るには十分だといえるのでしょうか? もし、よろしかったらご教授下さい。
>>536 new int a[3][3]まではいいけどその先が駄目。
newの後で要素へ代入していくしかない。
(int *)(*a) = new (int *)[3]; a[0] = new int[3]; //a[0] = {1,2,3}; a[1] = new int[3]; a[2] = new int[3];
ダライアス継承という言葉をたまに耳にしますがどういった物なのでしょうか?
554 :
98 :2005/05/27(金) 02:09:55
sourceforge以外で実際に作って勉強できそうなところないでしょうか? なんかどれに参加していいかも良くわからないし。途中から参加しても ついていけなさそう。
ダイダロス継承という言葉をたまに耳にしますがどういった物なのでしょうか?
ダルイデス継承という言葉をたまに耳にしますがどういった物なのでしょうか?
BOOST::lexical_castをパクってみたら、 'sw' は 'std' のメンバーではない!とか怒られたんですが 何がマズイんでしょうか? もちろんsstreamはincludeしてます。 問題部分のソースは if(!(s << src) || !(s >> dest) || !(s >> std::sw).eof())
>532 サンクス。 いろいろ書くと、チョット複雑なんだけど hDCが使えないので、Locate()とか、home()でカ−ソルを動かせると良いのですが・・ 元々、画面へ直接アクセスの考えがないから、駄目なんでしょうね。
560 :
デフォルトの名無しさん :2005/05/27(金) 09:28:29
使っているうちに使用メモリが増えていくアプリが、結構ありますが、 deleteしても、その解放したメモリ領域は、アプリが終わるまではOS側で再利用してくれないのでしょうか?
>>560 コンパイラ、ライブラリ、OSの実装による。
疑いを晴らしたいのなら、 new, delete を
OSのメモリ管理を直接使うように再定義して置き換えればよい。
>>561 レスありがとうございます。決まってないんですか。
折角隠蔽してくれているなら、こだわらない方が良いのでしょうか。
「OSのメモリ管理」で勉強しなおした所、(スレ違いですが)Windowsの場合は、すぐにでは無いけど、
後で可能ならば再利用してくれているんですね。あまり考えないことにします。
まあ大抵のOSではプロセスが確保したメモリは プロセスの解放時に全部解放されっから気にスンナ メモリリークが〜とかいうのはDaemonとか永続的に 走らせるアプリケーションじゃなきゃたいして問題じゃない というと怒る人がいっぱいいるけどね!
>>560 そういうのは大抵deleteがどうとかいう問題じゃなくて単純にバグでメモリリークしてるか、後で使うかもしれないからと使いもしないゴミを後生大事に抱え込んでるかのどっちか。
C++に限定した話ではないかもと思うのですが、質問です。 友人達と複数のゲームクラスをつくり、最後に一つにくっつけてゲーム完成を目指しています。 ただその際、メインのcppファイルがみんなのheaderファイルをincludeするため #define での宣言が重なってしまうかもしれません。 例えば #define DRAW_GAME_WIDTH 640 などです。ゲームによって幅が違うため、他の人が320などで宣言していたらコンパイル(プリプロセス)の際にエラーになってしまうでしょう。 これの解決策としてはどのような方法が一般的なのでしょうか。 それぞれはクラスを作ることになっており、グローバル空間には変数などを作らない約束にはなっています。 なのでstatic intでメンバー変数を static int DRAW_GAME_WIDTH = 640; といった感じのものを、クラス内で宣言させればグローバル空間を汚染しないかと考えました。 ですが変数ですので、#defineで置換したものに比べてわずかながら処理が遅いのかなと思います。 もう一つ enum{ DRAW_GAME_WIDTH = 640, DRAW_GAME_HEIGHT = 480, DRAW_XXX = 5 }; というのをクラス内で宣言させることを考えました。 ただ、気になるのはこの場合のスピードです。これは直値に置換されるのでしょうか? それとも変数扱いなのでしょうか。 初心者な質問ですが、よろしければご教授お願いいたします。(どれも見当違い! を含めて)
> ですが変数ですので、#defineで置換したものに比べてわずかながら処理が遅いのかなと思います。 遅くない。 遅かったとしても、本当にわずかだから気にしなくていい。 それを気にするレベルならC++なんか使うな。 > ただその際、メインのcppファイルがみんなのheaderファイルをincludeするため ありえない。
>>566 んなもんコンパイラによって違うから吐かれたコード見ろ。
第一そんなとこがボトルネックになるわけない。
最適化の基本は計測。
計測した結果、本当にそこがボトルネックになってるならそれから考える。
enumでやるのはconst staticが使えない環境で
無理矢理同じことを再現するEnam hackという手法。
本来のenumの使い方とは違うのでconst staticが
ちゃんと使えるならconst staticでやれ。
そもそも他人と被るようなウィンドウ幅みたいな定数を
グローバルにおかない事の方が間違いだがな。
>>566 enumはコンパイル時定数なのでろくに最適化をしないコンパイラでも問題ない。
ただし、単にクラス内定数が欲しいだけならenumよりstatic constを使う方が一般的。
ほかにもクラスの枠に縛られない定数が欲しいときには
1人1人が独自のnamespaceを持ち、その中でconstな定数を宣言する方法もある。
そもそも、画面の大きさは定数にするものなの?
>562 スレ違いではないと言う事が解らないほど、あほな奴だな。
#define定数 => コンパイル時に計算される enum定数 => コンパイル時に計算される、ただし値がint const static データメンバ定数 => 整数型ならば、コンパイル時に計算される 整数ならば、const staticデータメンバで行けばよい 浮動小数点のばあい、#defineのよい代案はない インライン関数で定義すれば、コンパイル時に計算する可能性が高いか
#defineはコンパイル前のプリプロセスで置換されるものだが。
プリプロセスを含めてcompilation phasesともいえる。
575 :
デフォルトの名無しさん :2005/05/28(土) 01:44:34
コンストラクタで何かにメンバ関数のポインタ渡すのって無理なんですか…? 型が違うってエラーの本来クラス名が出るところに_closureとか出てるんですが
577 :
575 :2005/05/28(土) 01:57:42
問題のメンバ関数をstaticメソッドにしたら渡せました… メンバにアクセスできる以上ポインタも取得できそうなものなのに もしかしてコンストラクタの中で そのクラスのポインタを受け取る関数にthis渡すのもできないんですか?
>>577 > もしかしてコンストラクタの中で
> そのクラスのポインタを受け取る関数にthis渡すのもできないんですか?
できる。が、一般的に危険だと言える。
580 :
575 :2005/05/28(土) 02:22:39
>>579 危険というのはコンストラクタで例外が起きちゃった場合とかですか?
それともコンストラクタ内でthisが使えるのは特殊な実装になってるんでしょうか
>>578 わかったかたがいるようなので貼りません。
>>575 コンストラクタでなければ渡せるのか?
メンバ関数へのポインタの書き方を知らないだけじゃないのか?
>>580 コンストラクタの中ということは、コンストラクタが完了していないわけで、
その型の完全なオブジェクトを期待している処理に渡された場合に整合性が崩れる可能性がある。
情報小出し厨は逝ってよし。
584 :
575 :2005/05/28(土) 03:06:37
>>581 >コンストラクタでなければ渡せるのか?
はい
>メンバ関数へのポインタの書き方を知らないだけじゃないのか?
そこまで馬鹿じゃありません
>>582 なるほどそれはそうですね
単純なオブジェクトプールを考えていて
プールクラスのAddメソッドに this を渡したいだけなので
マルチスレッドにでもしない限り大丈夫かな
下位クラスのコンストラクタでプールに検索かけられたらやばそうですが
BCBなヨカン。&つけて渡してみては。
> 問題のメンバ関数をstaticメソッドにしたら渡せました… 関数ポインタの使い方を知らないだけの予感
>>575 BCBのVCLは独自拡張で非staticなメンバ関数のポインタを扱えるようになっているが通常のC++では非staticなメンバ関数のポインタは取れない。
ついでにRTTIでもVCLのTObject派生クラスは通常のC++クラスと振る舞いが違う。
>>588 &をつけて明示すれば非staticな関数のポインタも取れないわけではない。
メンバへのポインタだから普通の関数ポインタのようには使えないが。
メンバ関数のポインタはそれぞれのオブジェクトに対するシフトを表しているから、 ->*とか.*を使わないとダメですな。 まあ、管理するのも面倒なので、boost::functionとか使いますが。
シフト……。せめてオフセットとかディスプレースメントにしとけ。
メンバ関数のポインタは普通の関数ポインタで実装されてる希ガス
>>593 MSVCでは単なる関数ポインタで実装されています。しかし、
構造体を使って実装されている環境もあります。一般的に、
メンバ関数へのポインタの実装は互換性を持ちません。
>>594 な、なんだって!?
それはかなり初耳だ。
>>590 コンストラクタ以外で CTest::Func が使えるのなら、それは標準とは違う動作だ。
>>596 む、そうでしたか。メンバ関数ポインタはあのサイトで知ってVCも&なしで通ったので、
&なしが普通だと思ってました。ご指摘どうもです。
>>595 Inside The C++ Object Modelでも読めよ。
>>598 その本に書いてることが本当だという保証はないだろ?
600 :
デフォルトの名無しさん :2005/05/29(日) 13:16:41
お前らあいかわらず下等だな
601 :
デフォルトの名無しさん :2005/05/29(日) 13:17:13
ヘタレがヘタレをバカにするのを見ていると本当に悲しくなる。
>その本に書いてることが本当だという保証はないだろ? 何だよその子供みたいな反論は・・・
>>599 少なくともお前のようなヘタレの頭の中よりはマシな事が書いてある。
>>599 書籍読んで、逆アセンブルしたコードと見比べればすぐ分かるだろ。
Inside The C++ Object Modelを読むまでも無く、 仕様で決められてないんだから関数ポインタがたとえどんな風に実装されていようが驚くような事じゃないだろ。
606 :
デフォルトの名無しさん :2005/05/29(日) 22:53:01
C++を勉強するのに 「詳説C++ 標準C++完全理解 第2版 大城 正典 (著)」 ってのを衝動買いしてしまった。 これで勉強して大丈夫か?
推薦図書読むのが一番の近道
詳説とか完全とか書いてある本は避けたほうが無難だよ。 本当にいい本は変な修飾語はつけない。
>604 そのコンパイラが標準に準拠してるほs(略 まぁどうでもいいが('A`)
Cからの移行の場合、どの本がいい?
K&R
逆戻りさせる気かい?
Cがちゃんと使えてるならいきなりC++3rd読んであとはEffectiveシリーズなりModern C++ Designなり。
Cからの移行というより、別物と思ったほうが。
スクリプト系からの移行なら、まずAccelerated C++
自分はいつもクラスを作る時、get_XXX, set_XXX と、パラメータごとに アクセス関数がずらーーっと、並べちゃうんですが、これは考え方そのもの が間違っているでしょうか? もうちょっとうまいやり方は、ないのか、 とか思いますが、なにか行き詰まってます。 意味不明なこと書いてるかもしれないですが、アドバイスよろしくお願いします。
>>616 その前に読点の使い方を勉強したほうがいい。
619 :
デフォルトの名無しさん :2005/06/02(木) 10:55:43
>>616 変数定義が多すぎるか、クラス間のつながりが強すぎるかのどちらかだと思うから、設計から見直す必要あり。
もしそれが変数だけを集めたクラスならアクセサは不要だけど。
class hoge { private: int FMoge; void SetMoge(int value); int GetMoge(); public: __property int Moge = { read=GetMoge, write=SetMoge }; }; ただし思いっきりコンパイラ依存
621 :
616 :2005/06/02(木) 11:32:26
ハロー(注意報)。えっと、こんなクラスを用意します。 Hoge1.h-------------------------------------- class Hoge2; class Hoge1 { public: void Fuga(Hoge2 h); }; Hoge2.h-------------------------------------- class Hoge1; class Hoge2 { public: void Fuga(Hoge1 h); }; Hoge1::Fuga()とHoge2::Fuga()をインライン関数にしようと思ったら (ここではインライン関数にする意義はあるものとします) Hoge1.h-------------------------------------- #include "Hoge2.h" class Hoge1 { public: void Fuga(Hoge2 h) { ... } }; Hoge2.h-------------------------------------- #include "Hoge1.h" class Hoge2 { public: void Fuga(Hoge1 h) { ... } }; では当然コンパイル通らないので、
Piyo.h--------------------------------------- class Hoge1 { public: void Fuga(Hoge2 h); }; class Hoge2 { public: void Fuga(Hoge1 h); }; inline Hoge1::Fuga() { ... } inline Hoge2::Fuga() { ... } とでもするしかなくて、1ファイル1クラスの原則が壊れてグダグダになるんですが、 何かエクセレントな手は……ないよね、やっぱし? せいぜい、 Piyo.h--------------------------------------- #include "Hoge1.h" #include "Hoge2.h" #include "Hoge1.inl" #include "Hoge2.inl" くらい?
624 :
622 :2005/06/02(木) 13:57:05
うあ、あちこち抜けてる。Piyo.h修正 Piyo.h--------------------------------------- class Hoge2; class Hoge1 { public: void Fuga(Hoge2 h); }; class Hoge2 { public: void Fuga(Hoge1 h); }; inline void Hoge1::Fuga() { ... } inline void Hoge2::Fuga() { ... }
>ハロー(注意報)。 だけ読んだ。
626 :
デフォルトの名無しさん :2005/06/02(木) 14:45:09
よく読んでないけど、ポインタ・参照を渡すようにする。 っていうか、実体を渡す場面が思いつかない。
>ハロー(注意報)。 何これ?波浪注意報?
ハロー(CV:井上瑤)
C++/CLIは正式に策定されたら別スレになるんだろうか
630 :
622 :2005/06/02(木) 18:17:31
ハロー(警報)。(好評らしいので)
>>626 実際には参照を渡しとります。
いずれにしても、インライン関数を定義するときに、その関数で使うクラスの定義が必要で、
それが複数のクラスで依存しあう場合にグダグダのガビガビになるんでどうしようかなあと。
波浪(again) Hoge1の参照しているHoge2, Hoge2の参照しているHoge1を templateで処理しとけ。
>>622 hallow (ground)
Hoge2のインライン関数の定義に際して、その前にHoge1のインターフェイスが
必要になる。逆も同様である。よって互いのクラス定義が見える状態である
必要がある。よって双方のクラス定義が共にそれぞれの関数定義の前方に
ある必要がある。よって
>>624 のような形か設計を変更する以外に手はない。
波浪(again)
>632
>よって
>>624 のような形か設計を変更する以外に手はない。
だから、templateつかって、実体化を引き延ばせって。
class Hoge1 {public:template<class T> void Fuga(T h){ h.Fuga(*this);}};
class Hoge2 {public:template<class T> void Fuga(T h){ h.Fuga(*this);}};
int main() { Hoge1 hoge1; Hoge2 hoge2; hoge2.Fuga(hoge1); }
どれも呼び出し側は綺麗に書けるんだし好きなの選べばいい希ガス。 定義側は五十歩百歩
ファイルストリームからバイナリデータとして入力するには ifstream fin(filename, ios::binary); のように open mode として ios::binary を指定すれば fin.read((char*)&(raw[0]), bufsize); で読み込むことができます。 しかしこの open mode は文字通り open 時のオプションらしく、 開いてしまうと途中でモードを切り替える方法がわかりません。 具体的には、cin からバイナリデータとして読み込んだり、 ひとつのファイルの N バイト目以前をバイナリ、残りをテキストとして 読み込んだりする方法がわかりません。 istream の ios::binary フラグを実行時の任意のときに切り替える方法はありませんか? gcc-3.3.3 の ios_base のソースコードだと static const openmode binary = openmode(__ios_flags::_S_bin); とあって、絶望的ですが(´д`)
二回openすりゃいいじゃん
>>635 >具体的には、cin からバイナリデータとして読み込んだり、
>ひとつのファイルの N バイト目以前をバイナリ、残りをテキストとして
前者は兎も角、後者は設計の問題。混在させるメリットが乏しい。
コンストラクタについて質問。 //コンストラクタ Scene::Scene() : m_pVB(0),m_pTexture(0),m_pTexture2(0) ←この部分について { //m_pVB,m_pTexture,m_pTexture2はSceneクラスで定義されてる、変数(ポインタ) } 上記の矢印の部分なんだけど、一体何をしているんでしょうか? 基本クラスコンストラクタへの引数渡しでもないようなんですが・・ よろしくお願いします。
変数の初期化
>>616 単純にプロパティ(パラメータ)が多過ぎるだけでは?
試しにアクセス関数が多過ぎると思うクラスを見せて欲しい
単純に「ずらーと並んでておかしいのかもしれない」と言われたら
メンバ変数とプロパティの区別が付いてない可能性くらいしか思いつかない
642 :
638 :2005/06/03(金) 01:16:58
>>642 どうでもいいことだけど追記
constメンバ変数や、メンバ変数が参照型のときなど、
「代入」ではなく「初期化」しなければならないときには初期化リストを使わなければならない。
そうでなくても、初期化の方がコスト面で優れているので、常に初期化リスト使うのおすすめ。
class X {
int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
double A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z;
public:
X() {
a = b = c = d = e = f = g = h = i = j = k = l = m = n = o = p = q = r = s = t = u = v = w = x = y = z = 0;
A = B = C = D = E = F = G = H = I = J = K = L = M = N = O = P = Q = R = S = T = U = V = W = X = Y = Z = 0.0;
};
}
のように、初期化リストだと煩雑すぎる場合だけ代入を使えと
えふぇシーに書いてあった
>>643 大丈夫、その例はコンストラクタで代入するのではなく代入用関数を用意すべきだから。
それも込みでの「えふぇシー」。
HogeHogeってどういう意味?ホゲホゲ? 10年経っても解らない
グーグル先生に聞けばいいと思うよ
>>641 C++にプロパティなんて無いのに、
メンバ変数とプロパティの区別ってどうゆうこと?
このhogeとかfoobarとか詳しい説明がどこにもないのは プログラマーなら誰しも一度は通る道だからだろうか
hogeはプログラマというよりUNIX文化発祥じゃなかろか
>>650 「気になる」のは誰もが通る道だろうけど、「どこにもない」ことはないだろう。
検索エンジンが無かったころじゃあるまいし。
>>649 C++みたいないい加減な言語使う場合こそ、
ちゃんとオブジェクト指向理解して下さい
Setter/Getterが必要なのはそのオブジェクトのプロパティ(特徴)であって
中でどんな変数でもってるかなんてのは問題じゃないです
複数のメンバ変数を合成した結果かもしれないし、そもそも変数じゃないかもしれない
クラスを便利な構造体と思ってるとプロパティ=メンバ変数と勘違いしてしまう
>>653 オブジェクトの状態を表示/設定する手段の一つに
「プロパティ」があるってだけで、それがメンバ関数だろうと
プロキシクラスだろうと、はたまたメッセージ送受信だろうと
んなこたあ問題じゃないです。
そして、C++ には「プロパティ」なるものは存在しません。
>ちゃんとオブジェクト指向理解して下さい
>>653 お前が言いたい「プロパティ」とやらは「アトリビュート」だろ。
>>654 653は、C++にプロパティがあるとは、言ってない。
C++にプロパティという文法はなくても、「オブジェクト指向」(と言っていいのか?)
にプロパティという概念はある。
クラス=プロパティ+メソッドみたいなもの?
C++ではプロパティを明示する方法が文法で区別されていない、
つまり、プロパティとその他のメソッドを同等に扱うことができるが、
それは扱ってもよい、と等価ではない、
と、653はいいたいのだと思う。
俺は同意。
つか、同じ人?
別人じゃないの? こういうマジレスで他人のフリする必要無いし。
そういう意味のプロパティなんてOOすら理解してないITドカタのORマッピングでしかつかってねーけどな。
またそうやってデタラメを自説の後ろ盾にするw
>オブジェクト指向」(と言っていいのか?) >にプロパティという概念はある。
たしかD&Eにはいわゆるプロパティをクラスに搭載することを検討したけど、 operator T()とoperator =(const T&)を持つクラスを置いたりGetter/Setterをメンバ関数にしたりすれば いいから没にしたとか書いてあったような希ガス。
質問どえす typedef struct _HOGE_ { floatx; floaty; floatz; }HOGE; typedef struct _HAGE_ { inta; intb; intc; }HAGE; typedef struct _HIGE_ { HOGEhoge; HAGE hage; }HIGE; std::vector< HIGE > m_hige; という構造体があって HIGE hige; hige.hoge.x = 1.0; hige.hoge.y = 2.0; hige.hoge.z = 3.0; hige.hage.a = 1; hige.hage.b = 2; hige.hage.c = 3; m_hige.pushback( hige ); m_higeにhigeを入れたとして、 このm_higeの中のhogeとhageの先頭アドレスを得るにはどうしたら良いのでしょうか? hige構造体の中身がhogeかhageだけだったら&m_hige[ 0 ]でいけるのですが・・・
&m_hige[0].hoge; と &m_hige[0].hage;
>665 それだとなんか上手くいかなかったdeath glVertexPointer( 3, GL_FLOAT, 0, &m_hige[0].hoge ); glColorPointer( 3, GL_FLOAT, 0, &m_hige[0].hage );
上手くいかないと言われても、何のことやら。
glVertexPointerとやらを調べたけど、3番目の引数はsizeof(HIGE)になるんでないか。 HOGEやHAGEの単純な配列じゃないんだから、少なくとも0じゃないと思うけど。
あでもvectorのstrideがsizeof(HIGE)でいいのかは俺は分からないや。とにかく0はいかんと思う。
>669 それで逝けました。ありがとうございまs・・・
>>669 それはsizeof(HIGE)で大丈夫。
>>670 頼むから2ターン目の質問で新事実を出さんでくれ。
>>666 までの流れだと完璧に煽りと同じだよ。
いくらなんでも「ライブラリの仕様を勘違いしてた」はNGだろ
>>408 をやってみたんですが
外部シンボル ""public: virtual void __thiscall hoge::Proc(void)" (?Proc@hoge@@UAEXXZ)"は未解決です。
とでてくるんですが、どうすればいいでしょうか
>>673 void hoge::Proc(void) を定義する。
675 :
673 :2005/06/06(月) 02:18:32
すみません、書き直す前の方送信してしまいました。
正しくは
未解決の外部シンボル "?CreateInstance@hoge@?A0xec65bdf2@@SAPAV12@XZ"
(?CreateInstance@hoge@?A0xec65bdf2@@SAPAV12@XZ)が関数 "void __stdcall Init(void)" (?Init@YGXXZ)で参照されました。
でした。
>>673 の方は
virtual void Proc() = 0;とする事で通りました。
>>675 応用効かせろよ。 hoge::CreateInstance の定義をよーく見直す。
677 :
673 :2005/06/06(月) 02:51:59
ごめんなさい、わかんないです。 CreateInstanceを定義するためには A* A::CreateInstance() { return new AImpl; }; これも公開側に書かないとだめで、そうするとAImplの定義が必要になるから class AImpl : public A { virtual void Proc(int x) { ... ;}; }; こっちも公開側に書かないとダメになって意味なくなっちゃうとおもうんですけど
>677 Windows 上でプラグインを DLL にしようとするなら、公開しないソース相当の部分とどうにかしてリンクする必要が あるんじゃない?公開しないソース相当部分を DLL にしてインポートライブラリを提供すればできるんじゃないかな。 EXE でもエクスポートできたような気はするが。 いっそのこと COM にしちゃえば?
679 :
673 :2005/06/06(月) 04:34:39
俺は402じゃないんで、プラグイン開発とかじゃないんですが プロジェクトを分散して開発するときにもこういう手法が必要なんじゃないかと思ってやってました
>>677 クラスAの宣言は公開するヘッダに必要。
A::CreateInstance()の定義はDLLに必要。(さらにDLLからエクスポートする必要がある)
A::CreateInstance()でAImplをnewしているからDLLにはAImplの宣言と定義が必要。
DLLを使う側にはAの宣言とA::CreateInstance()のDLLからのインポートが必要になる。
しかしAImplは不要。
681 :
673 :2005/06/06(月) 14:11:02
>>680 って事はその場合だとDll側が本体でそれを呼び出す側がプラグインのような形になってしまうと思うんですけど
Dllを呼び出す側に実操作が入ってて、DLL側でそれを利用するという形にしたい場合は
DLL側でAの宣言とA::CreateInstance()のインポートを行うという形でいいんでしょうか
>>681 そういう場合は、
struct {
A* (CreateAInstance)();
... // その他あれこれ
};
みたいなもの(へのポインタ)をEXE側からDll側に渡してあげるのが
良くあるパターン。
>>683 それをクラスとnewを使って実現する方法ってありますか
typedef struct{
class A;
} B;
int main(){
B b;
A* a = new b.A();
}
見たいな感じで出来ますか。
>>684 自分でやってみるか、ここで聞きたいなら要件を明らかにせよ。
何がしたいのか、何が気に入らないのかわからん。
ExeとDllの両方のヘッダ class B{ public: class A{ public: void act(); }; }; Exe側ソース typedef void (*C_PROC)(B*); void B::A::act(){ printf("test message"); } int main(int argc, char* argv[]){ B* b = new B(); HMODULE m = LoadLibrary("dll.dll"); C_PROC f = (C_PROC)GetProcAddress(m, "C"); f(b); int i; scanf("%d", &i); return 0; } Dll側ソース void __stdcall C(B* b){ B::A* a = new b->A(); a->act(); } ってやるとDll側で"構文エラー 識別子'b'"っていうエラーがでてaが初期化できない 改めて考えると何がしたいんだろ
>>684 newするには具体的なクラスの情報が必要なので、この件ではAImplを公
開しない限りnewを使うのは不可能。
A* a = new B::A;
>>688 その場合だとa->act();が未解決の外部シンボルになります。
試していないけどおおよそこんな感じで出来ないだろうか。 //共通ヘッダ class A { virtual void hoge(); }; A *CreateA(); void DestroyA(A*&); //DLL class B : public A { public: virtual void hoge() { MessageBox(0, TEXT("hello"), TEXT(""), MB_OK); } }; A *CreateA() { return new(std::nothrow) B; } void DestroyA(A*& a) { delete a; a = 0; } //EXE int main() { A *pA = CreateA(); pA->hoge(); DestroyA(pA); };
もうVCスレ逝けよ。
>>690 はあれだが
それ以外はVC関係なくないか
693 :
デフォルトの名無しさん :2005/06/06(月) 18:18:55
cfrontがダウンロードできる所を知ってる方はいらっしゃいますか? AT&TやBell研やらgoogle先生やらに聞いて見ましたがわかりません(´・ω・`)
>>693 無料でダウンロードできるAppleの旧々開発環境のMPWに
ついてたような気がする。バイナリだけど。
ようやくEffective C++ 3rd(英語版)が手に入った。 訳すの面倒だけど、見出しだけならぱっと見て読めるし、 2ndと内容的に重なっている部分も多いので、読むのはそんなに 苦にならない。
(∩゚д゚)アーアー
(∩゚д゚)イーイー
>>694 ありがとうございます。
でもおいらMac持ってないので、友人のMacに入れて…
>>695 おれも今日手に入れた。
で、なんとなく読んでみた Item 46 が
いきなり知らなかった内容でびっくりした。
質問です C++を始めたい初心者です おすすめのフリーのコンパイラとフリーのIDEがあれば教えて下さい
eclipse+cdt+gcc
Dev-C++
>701 それが一番最強な気がするのでそれ試してみます
vim+g++
707 :
デフォルトの名無しさん :2005/06/08(水) 04:37:10
char*const*pってどういうことですか? こんなところにconstついてるの初めてみました。
double型がとれる最小値は-DBL_MAXでよいのでしょうか?
>>707 その前に char const* p と char *const p の違いは分かる?
前者は「const char へのポインタ」で p 自体は変更可能だが、p が指す先は
リードオンリー。++p は OK だが (*p)++ とか *p = '\0' はダメ。
後者は「char への const ポインタ」で p の値は変更不可能だが、p が差す
先は変更可能。++p はダメだけど *p = 'a' は OK。
*が二度出てくるのは俺も初めて見たw
内側から読めばいいよ。 p is (modifiable) pointer to const pointer to const char pはポインタ。p自身を書き換えてもいい。 pの示す先(*p)は書き換え不可能なポインタ。*pは書き換えちゃいけない。 *pの示す先(**p)はchar。これは書き換えてもいい。
なんか一個constが増えてる予感。 下の三行だけ読んでくれ。
713 :
707 :2005/06/08(水) 09:35:53
>>709 、
>>712 なるほど。constにまつわる話ってポインタ自身とポインタが指す先とどっちも考えなきゃいけないわけですね。
d!
ちょっとまだ疑問なんですが、
>>709 さんの char const * p っていうのは const char * p と比べてどうなんでしょうか・・・?
>>713 char const * p と const char * p はどちらも同じ。
const int foo = -1; と int const foo = -1; も同様。
715 :
707 :2005/06/08(水) 10:12:58
同じだったんだ・・・orz どうもです。
>>708 大して違いはないばかりか非効率だと言われればそれまでだが、
-numeric_limits<double>::max();
の方がいいんじゃない?
別に効率は変わんないんじゃないの?
numeric_limits<double>::min();じゃだめなの?
>>718 min()は「表現できる正の最小値」だから、0に限りなく近い値を示す
(浮動小数点値の場合)
効率についてはパパよくわかんないけど、#defineはコンパイル時定数、
numeric_limits<double>::max()はgcc3.3.3だと
static double max() throw() { return __DBL_MAX__; }
だから実行時定数になる分、パラノイアからしたら効率が下がっているのかもしれない悪寒。
720 :
デフォルトの名無しさん :2005/06/08(水) 15:55:49
STLのvectorクラスのような動的に確保するもので、 2次元(orN次元)で扱えるものは有りますでしょうか?
vector<vector<T> >
>>716 そういう機能はさ、テンプレートパラメタで渡った型の
プロパティーをテンプレートクラス・関数側で調べるためには
どうしても必要だから標準ライブラリにあるんだけど
そうでなければ、別にどっちつかってもどうでもいいと思うんだが
723 :
デフォルトの名無しさん :2005/06/08(水) 18:39:15
724 :
デフォルトの名無しさん :2005/06/09(木) 02:23:09
>>719 numeric_limits<double>::min() (および DBL_MIN )って正の値だったのか。
型として取り得る最小の値を返してくれると思ってたから、
double については負の値だと思ってたよ。
型としての最小値を、テンプレート引数 T から取ろうと思ったら、
numeric_limits<T>::min() だと浮動小数点型の時にダメだし、
-numeric_limits<T>::max() だと整数型の時にダメになるってこと?
場合分けが要るのか?
INT_MINは0?
>>725 そういうことじゃなくて INT_MIN != -numeric_limits<int>::max() ってこったろ。
2の補数的には負の数のが一つ多い。
>724
Effective C++ 第2版の正誤表に関連する記述があるね。
>
ttp://aristeia.com/BookErrata/ec++2e-errata_frames.html >For a floating point type FPT, the minimum representable value is
>typically -numeric_limits<FPT>::max(), though the Standard does not guarantee this.
で、規格をさらってみますと
>ISO/IEC 14882:2003 18.2.1.2-2
> 1 Minimum finite value.181)
> 2 For floating types with denormalization, returns the minimum positive normalized value.
> 181) Equivalent to CHAR_MIN, SHRT_MIN, FLT_MIN, DBL_MIN, etc.
んじゃ、floating types without denormalization はどうやねんと考えると、
18.2.2 から DBL_MIN 等は C 相当。
>ISO/IEC 9899:1999 5.2.4.2.2-10
には FLT_MIN 等は minimum normalized positive floating-point number となって
いるので、結局 floating types については、min() は minimum positive normalized
value を返す、と考えてよさそう。
結局、numeric_limits<T>::is_integer により整数であるかどうかを判別する必要が
あるんじゃないすかね。
ところで有理数型なんてものがあった場合、min() は minimum positive number を
返すべきなんでしょうかね。
template<typename T> T minimum_value_of() { typedef std::numeric_limits<T> limits; return limits::is_integer ? limits::min() : -limits::max(); } これでいいのか? 判定を is_integer でやるのは、隙があるように思うが、 どうやって判定すべきかわからんな。
boost::multi_arrayを使用したソースをコンパイルしたところエラーが発生したんですが、 エラーメッセージはboost/mpl/aux_/integral_wrapper.hppでエラーが発生したとなっており、 どういった経路でインクルードされたのかを調べるだけでも嫌になりそうです。 こういった分かりにくいエラーメッセージに対処するいい方法はないでしょうか?
731 :
729 :2005/06/10(金) 16:55:27
>>730 すみません、環境はBCC5.5.1とBCC Developerを使っていて、エラメッセージは
エラー E2489 c:\boost_1_32_0\boost/mpl/aux_/integral_wrapper.hpp 45: オプションコンテキスト応答深度の上限を超過: 再帰をチェックしてください
これが25回連続出ます(26個目は「エラーあるいは警告が多すぎる」)。
STLfilt落としてみましたが、英語が読めなく使い方が分からないので、あとで翻訳かけながらじっくり読んでみます。
>>731 そりゃ、templateで再帰展開してる場合が多いしな。
>>732 のリンク先見たらfailと書いてあるし、だめみたいだね。
VC7.1かgccが他に有名だからそういうのにすべし。
gccをMinGWにしてSTLport入れれば、BCCなんて不要だし、
Dev-C++を入れればBCC Developerと同じような環境に出来る。
734 :
729 :2005/06/10(金) 18:47:28
>>732 >>733 そういうことだったんですか。
gccに乗り換えることにします。
どうもありがとうございました。
>>734 あーそうだ、gccは日本語対応してないので、ソ系ダメ文字の問題が
あるので(「ダメ文字」でぐぐるとわかる)、それだけは気を付けてくれ。
コメント欄に書いただけでエラーになる。解決法はその文字の後に'\'
を書くだけなんだが。
前に // 一覧表 と書いてエラーになり、何度調べてもプログラムに
間違いが無く、困っていたが、「表」がダメ文字だとわかり、// 一覧表\
と書いて解決した。
736 :
729 :2005/06/10(金) 19:15:07
コメント欄に関してなら、行末に空白や*を入れるだけで充分だと思う。 文字列リテラルはエスケープしなくちゃいけないから、要注意という点はその通りだけど。
そこまで頑張ってWinでgcc使うぐらいならVC++使へ
金があったらVC7.1買え。それが本当はいい選択なんだが。 秋には2005出るぞ。VC7.1買っておけば多分安く買える。
金がなくてもコンパイラ部分だけはタダで使えるしな
effective c++ 読んでて疑問に思ったんだが、 const Foo foo() { return Foo(); } っていう const オブジェクトを返す関数の戻り値を Foo f(foo()); みたいに非 const オブジェクトで受けた場合、RVOってできるものなの?
出来る
743 :
741 :2005/06/11(土) 02:16:54
最近のgccはコマンドラインで指定すればiconv使ってくれるしデフォルトでutf-8 を仮定する(もしくはロケールから推測する)と思うんだが。
日本語を使うときは、wchar_t や wstring って 使ったほうがいいんでしょうか? 使わなくても困ったことがないんですけど。
>>745 boost::regexを使うときとかに困る。
困ってから使えばいい。
748 :
745 :2005/06/11(土) 16:58:59
問題がでたら、その所で、変換すればOKってことですか? 私が以前使ったのは、半角と全角文字がまざっていて、 全角文字を1文字としたとき wchar_t に変換すると、 便利でした。 これが正常な使い方かどうかは、知りません。 あと、unicode を使うときは、wchar_t を使ったほうが よさそうな感じがして、悩んでます。 UTF-8 なら使わずにすむかなぁとか。 wchar_t や、wstring について解説してあるよいページってないですか? 見てみたんですが、どういうときに使うべきかっていうのは 見つからなくて。
>>748 UTF-8はマルチバイト文字の1種みたいなものだから
プログラム内部で使うのにはあまり向いていないと思う。
wchar_t使ってもエンコードがUTF-16だったりすると(以下略なわけだが。
仕様:本ソフトウェアはサロゲート・合成文字の類には一切対応しておりません。
そんなもん使うやつはいないからそれでいいよ
753 :
デフォルトの名無しさん :2005/06/14(火) 03:58:37
コンパイル時に数が確定しているstaticなインスタンスを数え上げて そのインスタンスへのポインタの配列を コンパイル時に自動的に確保するようなコードって書けますか? 例えばclass Fooがあったとして Foo a, b, c; としたときに Foo* AllFoos[3] = { &a, &b, &c }; のようなものをコンパイル時に作ってしまいたいんです テンプレートとコンストラクタとstaticメンバ組み合わせれば 出来そうな気がするんですけど、なかなかうまくいきません
Foo* AllFoos[3] = { &a, &b, &c }; の部分を自動で生成するってことか? >テンプレートとコンストラクタとstaticメンバ組み合わせれば >出来そうな気がするんですけど、なかなかうまくいきません これだと実行時じゃないの?
>>754 その部分の3ていう数字とか&aとかの部分です
というのもFooオブジェクトはスタティックな
インスタンスとしてしか存在しないんだけど
ソースファイルのいろんなところに散らばってしまうので
追加修正があったときにGrepしてカウントするのは非効率かなと
なんでコンパイル時にこだわってるかは、例えば
インスタンスの数が極端に少なければ全てのインスタンスに対するループ
for (int i = 0; i < Fooの総数; ++i) {
AllFoo[i]->SomeMethod();
}
がコンパイラの最適化によって展開されたりしたらいいなあと
for文をこうすれば for (int i = 0; AllFoo[i]!=NULL; ++i) { 修正箇所は一箇所じゃないの? Foo* AllFoos[] = { &a, &b, &c, NULL }; 最適化はよくわからんけど それだと仮に最適化されてもどうでもいいような速度じゃない?
>>756 わかりにくくてすみません
概念的にリスト構造なんで仮に配列で表現したまでで、
実際配列でやるのかは実装次第です
例えば実行時にリストを構築するとすれば
class Foo {
static std::vector< Foo* > s_AllFoos;
public:
Foo() { s_AllFoos.push_back(this); }
static void ForEach(std::unary_function<Foo, void> func) {
std::foreach(s_AllFoos->begin(), s_AllFoos->end(), func);
}
};
みたいにな感じになると思うんですが、動的に作らないクラスなので
コンパイル時に全てのインスタンスがわかるので
起動時に一々リスト構築するよりうまいやり方がないかなと思ったわけです
std::vector::push_back を呼び出すならコンパイル時には無理なんじゃないの?
>>753 俺だったら簡単なスクリプトを書いてそういうソースを自動生成するな。
適当に書いただけだと思うが、 static void ForEach(std::unary_function<Foo, void> func) { std::foreach(s_AllFoos->begin(), s_AllFoos->end(), func); } こんなの間違っても書くなよ
>>759 ですから、あくまで例です…
>>759 確かにスクリプトの領分かもしれません
一旦別の方向で考えてみます
>>760 すみません適当すぎましたw
762 :
デフォルトの名無しさん :2005/06/14(火) 23:11:40
超初心者が質問してもいいスレはこちらですか?(;´Д`)
いいえ
先輩にnullは使うなといわれました。確かに安易に使ってはいけないとおもいますが こうゆう場合はどうなのでしょうか? 俺がつくった関数 hoge getHoge() hogeが取れなかった場合nullを返す 先輩がつくった関数 boolean getHoge(hoge &h) hogeが取れなかった場合falseを返す どちらも呼ぶ側はif(!getHoge(...))です。ここまでしてnullを避けなければならないのでしょうか? 会社によってはこうゆうルールがあるのですか?先輩はnullはダメだとしか教えてくれませんでした
わざわざnullableまで作ったMSの立場は
>>765 もしかして、言語が Java じゃないか?
どんな事にせよ明確な理由も述べずに教条的に「〜しろ」言う奴は信用しない方が
信用はせず、イヤイヤ黙って従っておく というあたりが、おすすめの処世
nullアクセスで例外を吐いてくれるとはなんて親切なんだ! とC/C++使いとしてはうらやましいわけですよ
Windowsなら例外飛んでくるぞ。SEHのほうだがな
Windows上ではC/C++でもSEHになる。少し細工すればC++例外に出来る。 まあここはそんなスレじゃないけどな。
>>768 boolean とか、hoge getHoge() でなぜか null を返せるとか (hoge がポインタ型に
typedef されてるのか?) 俄には信じがたいんだが。
null 返すな bool にしとけ、ってのは CODE COMPLETE で見た気がする。
ポインタだとエラーチェックを端折るヤツが多くて後で苦労した、という実経験に
裏打ちされた話だったような。
ポインタだとエラーチェックを端折るヤツが多くてboolだと大丈夫という理屈はさっぱりわからんな。 ただポインタ返されてもそれがnewしたものかメンバのポインタかわからんので コードメンテ上良くない。
>>776 > ポインタだとエラーチェックを端折るヤツが多くてboolだと大丈夫という理屈はさっぱりわからんな。
理屈は分からなくても、実際にデバッグ工数減れば何でも良いよ。
ポインタでエラーチェックを端折るヤツはboolでも端折るんじゃないかと
コンストラクタの本体で、thisの指す先もしくは*thisを構築済みの 有効なオブジェクトとして扱う行為は正当でしょうか? class C; void func(C &); // Cのオブジェクトを操作する class C { C(){ func(*this); } };
782 :
デフォルトの名無しさん :2005/06/16(木) 23:55:35
クラスのあるメンバ関数を、初期設定により異なる メンバ関数に割り当てたいと考えています。 class Test { void a_(int x){cout << "a:" << x << endl;} void b_(int x){cout << "b:" << x << endl;} public: Test(unsigned int kind) : run( kind ? a_ : b_){} void (Test::*run)(int); }; int main() { Test test(1); test.run(3); <-- test.b_(3)が呼ばれてほしい return 0; } 上記のように試してみたのですが、test.run(3); の行で、 error:expression must have (pointer-to-) function type とエラーが出てしまいます。上記の例はどのように直せば うまく行くでしょうか?お分かりの方がいらっしゃいましたら、 ぜひご教授よろしくお願いいたします m(__)m
>>782 (test.*test.run)(3);
test.*run(3); じゃない? 試してないから知らんけど。
>>782 class Test
{
void a_(int x){cout << "a:" << x << endl;}
void b_(int x){cout << "b:" << x << endl;}
void (Test::*run_)(int);
public:
Test(unsigned int kind)
: run_( kind ? &Test::a_ : &Test::b_){}
void run(int x) { return (this->*run_)(x); }
};
>>782 class Test
{
void a_(int x){cout << "a:" << x << endl;}
void b_(int x){cout << "b:" << x << endl;}
void (Test::*pf)(int);
public:
Test(unsigned int kind)
: pf( kind ? &Test::a_ : &Test::b_){}
void run(int c)
{
(this->*pf)(c);
}
};
int main()
{
Test test(1);
test.run(3);
}
(test.*(test.run))(3);
>>782 汚すぎ。
せっかくC++使うんならポリモフィズム使えばいいだろが。
789 :
786 :2005/06/17(金) 00:08:01
かぶった。すまぬ。
何人いるんだ・・・
791 :
784 :2005/06/17(金) 00:10:00
皆質問に飢えてたりするのかねw
792 :
782 :2005/06/17(金) 00:11:40
一気にすごい数の回答が。。ありがとうございますm(__)m 今からそれぞれ試してみます!
>>791 飢えているなら俺から質問
voidってなに?
全然関係ないが > <-- test.b_(3)が呼ばれてほしい これは無理だろ
ひっかけ問題か。全員不正解!
>>794 783- の回答でできたんじゃないの?
797 :
784 :2005/06/17(金) 00:22:40
>794 Ω<ナ、ナンダッテー
>>798 thx
ホントにvoidだけにスルーされたかと思った
void* what_about_this(void);
>>796 > Test test(1);
となってるからrunにはTest::a_が入る。
だからTest::b_は呼ばれない。
804 :
782 :2005/06/17(金) 00:32:23
>>785 =
>>786 は無事うまく行きました。文法的に
何をやっているかも理解できました。なるほどこうやればいいんですね。
ありがとうございます。
>>783 >>787 は共に文法的に同じ事を意味しているようですね。
文法的にどのような構造になっているのか
よく理解できていないのですが、無事うまくいきました。
何だか分からんが、すごいです。。
>>784 は残念ながら私の環境ではエラーになってしまうようです。
>>788 確かに、きたないですね。。ただ、対応すべき関数(a_,b_など)がいっぱい
ありすぎるため、いちいち子クラスを作ると大量にクラスができてしまう
ので躊躇してしまっています。
皆様、これくらいの事は一瞬で分かるようで、
すご過ぎて尊敬してしまいます。
大変勉強になりました。どうもありがとうございましたm(__)m
>>782 お前はすごいよ
俺なんてvoidすらわからねぇんだから自信もて
806 :
782 :2005/06/17(金) 00:35:25
>>795 よし、皆ひっかかったぜ!
というのは大嘘で、単なるミスです。。
すみません、ご指摘ありがとうございました。
>>804 どういう経緯でそれが必要になったか知らないが、設計考え直したほうがいいぞ。
>804
>>783 等の形は、
「メンバ関数へのポインタ(変数)は、そのクラスのメンバであるとは限らない」ことから。
変数を指定するためのtest.runと、
そのメンバ関数ポインタを呼び出すインスタンスとしてのtest
この2つが必要だということ。
関係ないんだが 会社とかでさ パッケージを保守する仕事してたら ソースのFOR文とかに iとかjとかつかってるのがあると萎えるのはなぜ
i, j よりも for が大文字なのが、一体どんなマクロかと思って萎える。
>>810 特に深い意味はなかったけど何で大文字にしたんだろ
812 :
782 :2005/06/17(金) 00:43:28
>>807 そうですね。色々ほかの可能性も考慮に入れて見る事にします。
>>808 なるほど。。超勉強になります。どうもありがとうございます。
class TestBase { public: virtual void run(int) = 0; }; class TestA : public TestBase { public: void run(int x){cout << "a:" << x << endl;} }; class TestB : public TestBase { public: void run(int x){cout << "b:" << x << endl;} }; class Test { public: Test(int kind) { if (kind) tb = new TestA(); else tb = new TestB(); } virtual ~Test() { delete tb; } void run(int x) { tb->run(x); } private: TestBase* tb; }; int main() { Test t(1); t.run(3); return 0; }
815 :
813 :2005/06/17(金) 13:26:01
>>814 俺も勉強中なんだ。リファクタリング希望。
816 :
813 :2005/06/17(金) 13:28:53
こんなか? class TestBase { public: TestBase(string n) : name(n) {} void run(int x) { cout << name << x << endl; } private: string name; }; class TestA : public TestBase { public: TestA() : TestBase("a:") {} }; class TestB : public TestBase { public: TestB() : TestBase("b:") {} };
>>814 書いてからよく見たらほとんど変わらなかった。
class Runnable { // 仮想デストラクタ省略
public:
virtual void run(int x) = 0;
};
class A : public Runnable {
virtual void run(int x) ){ cout << "a:" << x << endl; }
};
class B : public Runnable {
virtual void run(int x) ){ cout << "b:" << x << endl; }
};
class Test {
public:
void setRunnable(Runnable* r) { r_ = r; } // setterでさしこむ
void run(int x) { r_->run(x); }
private:
Runnable* r_;
};
818 :
デフォルトの名無しさん :2005/06/17(金) 14:50:07
こうしてみると
>>785 あたりが意外と悪くない気がするなぁ。
別クラスにすると場合によってはTestのポインタを(TestA,TestBとかに)引き渡さなくちゃいけなくなるし。
std::stackって最後に追加したものだけしか要素を参照できませんよね. 先頭とその次の要素まで参照できるstackがほしいんですが,どう実装するのが良いんでしょうか.
stack使わずにdequeなりvectorなり使えば?
821 :
819 :2005/06/17(金) 19:52:05
>>820 とりあえず今は std::deque で実装してるんですが,先頭から二つの要素が見える
stackとしてしか使っていないので,できる限りstackっぽくしたいんですよねえ.
std::stack stk; // ゴミ箱があるとする tmp = stk.top(); // ふたをコピーして stk.pop(); // ふたを開けるとする // stk.top(); // 中身を見てうげー stk.push(tmp); // ふたを閉める これしかないんじゃ?
>>818 うん。
生のメンバ関数ポインタを boost function に変えれば、
ほぼ 785 の通りにできるよね(呼び出し時にもthisとか
いらない)。
boostのソース追ってて気になったんですが、 メソッドの引数で(foo<T> const & r)みたいな constの位置ってどういう意味なんでしょうか? (char * const bar) みたいのがポインタ不変宣言なのは知ってるのですが 参照の前にconstがあるのは知りませんでした…
const T と T const は同じ
クラステンプレートでメンバフィールドの特殊化ってできますか? メソッドならtemplate<> ClassName<特化型>::SomeMethod() みたいな感じにするのはわかるんですが、 例えばインデックスの型によってコンテナを使い分けるクラステンプレート template<typename valueT, typename indexT> class MyTable { indexT add(const valueT& value); void remove(const indexT& index); valueT find(const indexT& index); } みたいのを、具体的にどうやって記述して良いのかわかりません 数値ならハッシュテーブル、文字列なら二分木、みたいな感じでやりたいのですが…
template<typename valueT, typename indexT> class MyTable; template<typename valueT> class MyTable<valueT,int> { //ハッシュで実装 }; template<typename valueT> class MyTable<valueT,char*> { //木で実装 }; これじゃダメか?
>>828 あー…なるほど…クラス自体を特殊化してしまうんですね
本当にメンバフィールドの型だけを変えたいってのなら、Boost 使うとこんな感じ? typedef typename if_<is_integral<indexT>, hash<indexT, valueT>, tree<indexT, valueT> >::type containerT; でもメソッドの実装ごと切り替えたいなら実装用のクラスを作ってテンプレート引数で切り替えるというのも 有りかと。まー >828 と同じだけど template<typename valueT, typename indexT> class MyTable : public MyTableImp<valueT, indexT, is_integral<indexT>::value> {}; template<typename valueT, typename indexT, bool b> class MyTableImp { // ハッシュテーブル実装 }; template<typename valueT, typename indexT> class MyTableImp<valueT, indexT, false> { // 二分木実装 };
>>830 ありがとうございます
テンプレートをboolリテラル?的に扱うのは
覚えた方が良さそうですね
ガウス・ジョルダン法を用いてn*(n+1)行列を変形する関数を作っているのですが、 変形する関数(GaussJordan)は行列のクラスのメンバ関数にしていいと思いますか?
俺ならそうはしない。 インタフェースは必要最小限がいい。
テンプレートのことで聞きたいんですが, class A { //普通なクラス }; template <class name> class B{ //テンプレートクラス }; があったとします。 そして、このテンプレートクラスを使うために"型"を指定してインスタンス化 するわけですけど b<型> object; この"型"に一番上に書いた「class A」のような 自分で作ったクラスを"型"として指定できるのでしょうか? int型などは、普通に指定できるのはわかっているんですが・・・・ ご教授お願いします。
できる。
837 :
デフォルトの名無しさん :2005/06/21(火) 22:27:09
クラスのメンバ関数に関してなんですが クラスのインスタンスにはメンバ関数へのポインタは含まれてないけど、 そのかわりに○○○って所へのポインタを持っていて メンバを呼ぶと○○○からたどって目的のメンバ関数を呼び出すって感じだったと思うんですけど ○○○って何て名前ですか? たしかアルファベット3文字だったと思うんですけど。
vtblのことか? ちなみに仮想関数だけな。
vtbl?
DVD
>>833 C++って何でもメンバにしがちだけど
俺もそっちの方が自然だと思うな。
例えばvectorクラスだったら、
長さを返すlengthはメンバでいいと思うけど
正規化するnormalizeは関数の方がいいみたいな。
normalize なんかは非常によく使うので、 メンバ、関数共に存在して欲しい
自己書き換えで const でないメンバ関数 normalize (戻り値なし)と、 正規化した結果を返す関数 T normalize(const T&) の両方欲しい。 効率の観点から。
俺はlengthもフリー関数で良いと思うけど。
効率の問題があるなら
>>844 みたいにするか、成分ごとの操作を許すかだな。
ノーマル関数というかクラスのstatic関数にしないか普通
もれのところでは class Vector { float Norm() const; Vector& Normalize(); static Vector Normalize(const Vector& v); inline float Length() const { return Norm() }; }; みたいになっている しかしガウスジョルダンだかしらんけど 用途が極限られてるメソッドは 独立させた方がいいんじゃないかね
わかってないから
850 :
846 :2005/06/21(火) 23:42:01
あれ?俺だけ?
例えば
>>847 のように
Vectorクラスに関連してるが
インスタンスの情報は必要ないユーティリティ的な関数ってstaticにするけど
値を返す方は漏れも普通の関数にするな。
>>845 >効率の問題があるなら
>>844 みたいにするか、成分ごとの操作を許すかだな。
「成分ごとの操作を許さない行列クラス」ってちょっと使い難いと思う。
>>847 >Vector& Normalize();
なるほど。 v2 = (x - y).Normalize() * 2; とか効率よく出来るわけね。
>>848 普通の関数にするのは、Vectorみたいなデータクラスの操作を一々
メンバ関数にしてられっかょ、何か追加するたびに毎回Vectorみたいな
基本的なクラスに変更が入んのか、というようなことだと思う。
基本的には同意だが、ベクタぐらいならともかく、 外に見せるインターフェースと内側での実装の間に 多少なりとも違いのあるクラスなら、メンバ関数にして内側の実装を直接いじった方が 効率がいいかも、とは考えるかな。
>>850 俺なら同じファイルに入れるだけにするな。
static関数もカプセル化のために使いたい。
ん、いきなり流れを立って申し訳ないけど。 VC6でbool形に true to falseしか代入させないようにするって出来ますでしょうか? VC6だとこれ通っちゃうんですけど・・・ bool foo = (float)1.0; bool foo = (double)1.0; TRUE,FALSEの代入も抑制したいんです。
boolean型新たに作るとか
boon b;
860 :
855 :2005/06/22(水) 08:38:43
無理ゆーなーヽ(`Д´)ノ 一時オブジェクトを生成させることによって、 コンパイルエラーをわざとと吐かせることは可能なんだぞ。 あとはグローバルの bool operator = をオーバーライドする方法さえあればいいのに。 int f(void){return 1;} #undef TRUE #define TRUE f(); bool foo1 = TRUE;
時間と手間をかけるほどの意味なし。
>>855 VC7.1では1と0のリテラル以外なら整数・浮動小数点数共に警告が出た。
>>835 さん回答ありがとうございます。
で、また疑問が出てきました。
あの、.netを使ってるんですけど
テンプレートのことで
.h
でテンプレートクラスとその関数を定義
.cpp
でテンプレートの関数を実装
でビルドするとリンクされてませんエラーが出ます。
このスレの過去ログで、vc6ではこのcppとhの分離が出来ないということがわかりました。
現在でもこのcppとhの分離は出来ないのでしょうか
よろしくお願いします。
テンプレートは全部ヘッダに書く。これC++の決まり。
exportでできるけど 可能な実装見た事ないなぁ
>>865-867 ありがとうございます。
なるほど。
決まりだったのか・・
もやもやした疑問が解けてかなり助かりました。
これで、作業が進めれれるぞ!(・∀・)
870 :
855 :2005/06/22(水) 23:36:18
無理かもしれないけど、boost/mpl で何とかならんのかー('A`) 仕方ないので、comp lang c++ λ...逝って来ます・・・。
>>855 VC6って、「警告をエラーとして扱う」オプションとかないの?
あったと思う。
875 :
855 :2005/06/24(金) 00:55:52
>>874 おおぅ。 それっぽいことが長々と書いてある。塾読してみます。サンクス。
>>871 [プロジェクト]-[設定...] メニューで出てくるダイアログの [C/C++] タブの中に
「警告をエラーとして扱う」 オプションがあるよ。
コマンドラインからなら /WX かな。
>>876 んなオプションどっかにあった?
VC.NET2003で以下のようにシングルトンを実装したいのですが、 error LNK2001: 外部シンボル ""private: static class Hoge * Hoge::_h"(?_h@Hoge@@0PAV1@A)" は未解決です。 というコンパイルエラーが出ます。 class Hoge{ public: static Hoge& GetInstance(); private: Hoge(); static void Instance(){ static Hoge h; } static Hoge *_h; }; Hoge& Hoge::GetInstance(){ return *_h; } Hoge::Hoge(){ _h = this; } コンストラクタHoge()からstaticクラスメンバ*_hへのアクセスが、 外部シンボルとなってしまうのはなぜでしょうか?
>>878 コンパイラのエラーそのまんまの意味じゃん?
どっかのcppにHoge * Hoge::_h = NULL;と書いとけ
ソースファイルに Hoge* Hoge::_h; って書かないと。
882 :
878 :2005/06/25(土) 20:19:11
解決しました。 ありがとうございました。
883 :
デフォルトの名無しさん :2005/06/26(日) 08:31:08
2つのクラスA,Bを作り、それぞれにヘッダファイルとソースファイルを用意したとき、 /* A.h */ #ifndef _A_H_ #define _A_H_ #include "B.h" (中略) #endif /* B.h */ #ifndef _B_H_ #define _B_H_ #include "A.h" (中略) #endif としてしまうと、 A.hを読み込むと、B.hが読み込まれますが、さらにB.hがA.hを読み込むとき #ifndefのせいでB.hではAが定義されていないとエラーが出るのですが 解決する方法はございませんでしょうか?
>>884 B.h から #include "A.h" を削除。
>>885 B.hを読み込むファイルもあるのです。
根本的に変更するべきでしょうか
>>884 ,886
A.h から #include "B.h" を削除。
AとBは互いを参照するほど強い関係なのだから、1つのファイルにまとめてもいいだろ。 1つのファイルにまとめるほど強い関係でないのなら、クラス設計的にもっと何とかなるだろ。
>>886 B.h は A.h にインクルードされているんだから、A.hをインクルードすればいい。
>>887 それだとA.hを読み込んだときに
「Bがない」とエラーが出てしまいます。
>>888 ,889
考えてみます。
ありがとうございました。
>>891 ---------[A.h]-------------
#include "B.h"
class A
{
B *pB;
;;
};
---------[B.h]-------------
class A;
class B
{
A *pA;
;;
};
---------[main.cpp]-------------
#include "A.h"
int main()
{
A a;
B; b;
;;
};
>>892 そんな方法もあったのですね。
ありがとうございました。
>>892 どちらか片方がポインタだけの利用で済むならそれが答えになるだろうが、
884 はそんな情報は示していない。
>>884 インクルードガードの先頭 _ はやめとけよ。
情報なんて不足しまくりだし、ひとつの例を示しただけですが。
>>894 ,896
情報が足らずにすいませんでした。
ポインタでない場合でもできるような方法はありますでしょうか?
>>895 eclipseでクラスを作ると自動的についてくるのでそのままにしていたのですが
なにか問題が発生しますか?
C/C++では規格上、アンダースコア( _ ) やダブルアンダースコア( __ ) で始まる識別子は、 処理系で予約されている。だから使うべきではない。 でも、現実問題、使われまくりだったりする。
899 :
855 :2005/06/26(日) 13:21:33
ポインタでない場合、ヘタすれば無限再帰でコンパイラも殺せる テンプレートをマンセーしておく。
>>897 前方宣言によって有効になる記述はポインタ以外にもいろいろあるが、
一言で言うと、不完全な型しか要求しない記述なら大丈夫。
「完全な型」、「不完全な型」の詳しい意味は、自分で調べてくれ。
つーか#pragma onceでいいじゃん。 インクルードガードなんて馬鹿馬鹿しいから 消しまくってるよ。
特定OS上の特定処理系でしか絶対に使用しないとわかっているものなら それでも良かろう
905 :
デフォルトの名無しさん :2005/06/27(月) 08:47:59
QDBMというDBMを使っているのですが c++でvistaを使う為に xvilla.hのソースコードの#include<villa.h>を#include<vista.h>に変えてみたり アプリケーションのソースコードに#include<vista.h>を書いてみたのですが 普通にvilla用のデータベースファイルが作られてしまい、villaとして機能してしまっているみたいです。 vistaをc++で使う為にはどうしたらいいのでしょう?
むしろインクルードするヘッダファイル名を変えただけで 置き換わるほうがまれだろう
907 :
905 :2005/06/27(月) 09:23:12
villa.hのシンボルをマクロでオーバーライドしているので ヘッダファイル名をvista.hに変えるだけで良い、とマニュアルに書いてあって、 C用だと確かにヘッダのファイル名を変えるだけで上手く行くのですが C++用はxvista.hが無いしxvilla.h内のvilla.hのインクルードをvista.hに変えてもダメだし マニュアルにはC++はCとほぼ同じAPIが使えると書いてあったけど(ほぼなのでC++用vistaは無いのかもしれないけど) C++用vistaについて何も書かれていないし、QDBMのWEB上の情報自体が少ないんです。 ただ、かなり優秀なソフトなので使っている人は割と多いのではと思うのですが 分かる方が居たら教えて欲しいです。
やっぱりC++使う以上は、継承とかバリバリ使えないといけないのでしょうか。 ウィンドウズでVisualC++とか使っている範囲では、 殆どそんなテクニックは意識したことが無いのです。
ぷらぷらでは aho.h class boke; //クラスの名前だけどっかにあるよ宣言 //#include "boke.h" いんくるーどはしませんよ class Aho { boke* m_pBoke; //ポインタ形だからクラスの名前だけあればいけるよ }; とやってるんですがここでbokeが typedef struct tag_boke { ... }BOKE; typedef struct tag_boke* LPBOKE; とCライクに書かれている場合はどのようにbokeクラス宣言すればいいのでしょうか? インクルードせずに class Aho { LPBOKE m_pBoke; }; と書きたいのですが・・・。 typedefされたLPBOKEをインクルードせずに見る方法ってあるのかな。
あるわけねーだろチンカス そんくらい悟れや
ないですよねぇ・・・。 動機としては class Aho { private: Boke* m_pBoke } だからAhoはBokeを実装手段としてプライベートに持つ つまりAhoクラスを使うクライアントにはBokeクラスを知る必要がない。 ということでインクルードはしたくないし、不必要 だったのですが、 今時typedefでLPなんとかとやるメリットは どこにあるのかと思ったチンカス君でした。
こうなるだけではないの? class tag_boke; class Aho { tag_boke* m_Boke; };
typedef struct tag_boke* LPBOKE; この行があれば充分だけど
結局タグなんたらって書いてますが・・・ いちいち#ifndef LPなんたらもめんどいし・・・。
boke_fwd.h struct tag_boke; typedef struct tag_boke* LPBOKE;
わざわざ二箇所でtypedefするのも嫌だな・・・。
boke.h #include "boke_fwd.h"
918 :
デフォルトの名無しさん :2005/06/27(月) 17:08:37
試してみたら出来た。MSすげぇ コレが出来たら何でもありじゃん。 //struct struct_boke //{ //int a; //}; class class_boke { int a; }; __if_exists( ::struct_boke) { class aho { ::struct_boke* pboke; }; } __if_exists( ::class_boke) { class aho { ::class_boke* pboke; }; }
919 :
918 :2005/06/27(月) 17:14:23
と思ったけど 今回のケースでは役に立たんね ガクッ(x_x;
>>920 お前はそこの管理人よりもずっと頭が悪いんだから無理です。
そいつは東大の学生だぞ。
>>921 なんちゅー答えだw
お前は馬鹿というより幼い感じだな。
c2html?
>>920 そんな阿呆な質問してる奴のソースなんて、見せられても逆に困る。
>>920 htmlのソース見てコピペすればすむことだろ。
うちは Source HighLight の Win32版つかってる。
要するに<PRE></PRE>でいいんじゃねーの?
Doxygenでも使っとけ
カクカクシカジカさんにも置いてあるね>cpp2html
932 :
デフォルトの名無しさん :2005/06/28(火) 10:53:53
クラス図を書いていて思ったのですが、C++で設計する場合、 グローバル変数は1つも使うべきではいないのでしょうか。 使ったほうが便利なケースはいくらでもありそうな気がして ならないのです。 設計のスキルはまだ全然ないのですが、他のソースを リバースエンジニアリングしてみてもほとんどのソースで グローバル変数が使用されている様子ですが・・・。
タトエバどんな場合?
大半はクラススコープ/ファイルスコープのstatic変数だろ とは言っても、グローバル変数はいくらでも使われてるだろうけど。 errnoとかcoutとかだって、その一種と言えないこともないし。
略して糞ース
938 :
デフォルトの名無しさん :2005/06/28(火) 11:47:00
>>936 糞ソースじゃないソースを提示してみろと言ってみる
糞だろうが何だろうが 提示できるソースをいきなりホイホイ挙げられるかよ
>>939 逆ギレキタ━━━━(゚∀゚)━━━━!!
まーオープンソースのものって大抵グローバル変数使われちゃってるわな。
942 :
デフォルトの名無しさん :2005/06/28(火) 17:44:41
オープンソースやるやつは露出狂
>>943 背景として、C++に限らずlisp・perl・おぞましいN88-BASICなどのソースコードも
提示することがあるから、それらすべてに対応してる既存品が楽かなと。
>>932 真にグローバルな変数は使わない方がいいと思う。
他のプロジェクトではもっとまともなのかもしれないけど、
過去のC/BASIC/Fortranのソースコードから再利用したり
担当者が4人ほど変わって引き継いだりそもそも担当はプログラム経験がほとんどない人だったり
仕様が毎日か長くて毎週変わったり
それを5年ほど続けると、もうすごいことになっています。
・・・結論まで書こうと思ったが鬱になったのでもうどうでもいいや…
真と書いて「マジ」と読む?
グローバルで管理したいデータってどうしたらいいのでしょう。 というのが、今回の問題です。
そんな貴方にSingleton
なにもわかってないな
>>946 グローバルで管理したい理由、プログラムの規模、プログラムの寿命などによって答えは変わる。
プログラムの規模、って言っても、表現に困るよね。 規模なんて相対的だし。客観的な表現方法ってあるの?
952 :
デフォルトの名無しさん :2005/06/29(水) 10:41:33
>>950 「プログラムの規模」って言いたかっただけでは?
>>950 明確な基準はないと思うけど、
「いつ、どこで、どんな操作がされるかを把握できる」
かどうかに懸かってるんじゃなかろか。
例えばログファイルにメッセージ書くクラスがあって
それが「書き込み」という操作しかなければ
グローバルにインスタンス作ってもいいわけで。
グローバル変数の欠点を理解してない意見も混ざってる気がする。 publicでstaticな変数との違いは、 クラス宣言に書く必要が無いからこっそり使ったりする事が可能だって事と、 大規模なプログラムの場合、名前の衝突が管理出来なかったり、 VCみたいな賢いIDEが使えない場合に型の確認が面倒だって事くらいだろう。 publicでstaticな変数にも共通する欠点は色々あるから、 それを許すかどうかもはっきりさせた方がいいわな。 どっちにしろ、「使わなくても出来るけど手抜きでやってる」って事を意識しとくべき。
MFC使うとグローバル変数の一個大隊がついてくるからなぁ。
グローバル変数が0で済むプログラムってのもどんだけちっちゃいんだよって思うけど。 まぁクラスにきちんとまとめて、それも全部publicとかじゃなくて丁寧にアクセス制御しとくんだろうな
クラステンプレートの内側に、クラステンプレートの特殊化版をネスト定義できない件について。 ふぬおおおソースがきちゃなくなるんじゃあああヾ(`□´)ノ
コンパイラが古いんジャマイカ。 VC++6.0ではネストできんかった。 VC++.NETではネストできた。
960 :
959 :2005/06/29(水) 20:43:44 BE:140478645-
.NET 2003ね。
>>959 g++だと意図的に対応していないようであります
標準のappendixで禁止しているかららしい。
関数内関数定義とか、templateの宣言・定義の簡略化とか
C++0xで変わったらいいなあ。
WindowsプログラミングをしようとするとWinMainとWndProcの兼ね合いとかでほとんど無理だけどな>グローバル0
>>962 とりあえずフレームワークさえ構築してしまえば
表だったグローバル変数は使わなくて済むと思う。
まぁ俺は安易にグローバル変数使っちゃう族だが。
いや、ウィンドウプロシージャごときで静的変数なんかつかわねーだろ普通
このスレの1が変なのか
STLスレを立てるやつが変。
デバッグしてみたら -1.#IND000000000 -1.#INF000000000 こんな数字が変数に入ってるんだけどこれは何なのでしょうか?
>>969 数値以外の値。
前者はなんだろう。
後者は負の無限大かな?
いずれにしても、C++の問題というよりデバッガの問題だよな。
971 :
デフォルトの名無しさん :2005/06/30(木) 16:39:51
INDって何の略ですか?
>>969-971 前者は「不定」で恐らくは-0/0の結果。
後者は「無限大」で恐らくは-1/0の結果。
なんかシンプルな行列やベクトルライブラリありませんか? DirectXのD3DXVECTORぐらいでいいのですが、環境に依存しないやつほしいです。
boostなり自分で作るなり
>>974 boostのベクトルも探してる最中なんですが、
2次元3次元のベクトルよりquaternion、octonionやらが先に見つかってしまいます。
どこかな・・・。
>>975-976 ありがとうございます。
そーゆーのです。
といってもいろいろあると目移りしてしまいます・・・。
スレ違いかもしれないどうしようもない質問をしてしまうのですが 自分は今までプログラムをやった事がないものの、来週からC++をやろうとしています ここで質問ですが、C++をやるに当たって最初に必要なものはなんでしょうか?何か買う必要があるのでしょうか? 幾ら調べても本当にわけが分かりません、コンパイラーというのが有れば出来るものなのでしょうか?ご指導をよろしくお願いいたします。。
>>980 どうして突然C++をやることになったのかが興味がわきますね。
とりあえず友達にプログラマを見つけて、ある程度のレベルまでは教えてもらうのが早いかと。
984 :
デフォルトの名無しさん :2005/07/01(金) 02:28:49
struct A{ int a; }; A a[10]; for( A* i = a; a != a + 10; ++a ) a->a = 10; これをSTLの関数オブジェクトまたはboostのbindを使って置換したいのですが どうすればいいでしょうか?
985 :
984訂正です :2005/07/01(金) 02:29:38
struct A{ int a; }; A a[10]; for( A* i = a; i != a + 10; ++i ) a->a = 10; これをSTLの関数オブジェクトまたはboostのbindを使って置換したいのですが どうすればいいでしょうか?
986 :
デフォルトの名無しさん :2005/07/01(金) 02:30:36
>>984-985 using namespace boost::lambda;
std::for_each(a, a + 10, bind(&A::a, _1) = 10);
>>985 boost::bind ではなく boost::lambda::bind だけど。
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
namespace bl = boost::lambda;
std::for_each(&a[0], &a[10], bl::bind(&A::a, bl::_1) = 10);
989 :
デフォルトの名無しさん :2005/07/01(金) 03:10:18
990 :
デフォルトの名無しさん :2005/07/01(金) 05:13:32
class func : std::unary_function<int, void> { public: result_type operator( ) ( argument_type i ){} }; std::vector< int > v; boost::bind( &std::for_each, _1, _2, _3)( v.begin(), v.end(), func()); すいません、また教えてください・・ VisualC++7.1なんですが、これのコンパイルが通りません。 error C2780が大量に出ます。さっぱりわかりません。
991 :
デフォルトの名無しさん :2005/07/01(金) 05:44:56
&std::for_each を &std::for_each< std::vector< int >::iterator, func > に直しましたが まだ駄目です。 bind関数の一番目の引数である「v.begin()」に対して 「1 番目の引数を '_STL::vector<_Tp>::iterator' から '_STL::vector<_Tp>::iterator & ' に変換できません。」 「'const' に対してではない参照は 非左辺値へバインドできません。」 とでます。どういう意味でしょうか?
煮詰まったので質問します。
型AとBが同じ型のときtrueを、異なる型のときfalseを返すクラステンプレート:
template <typename lhs, typename rhs>
struct is_equal {
tempalte <typename T> struct proxy { enum { type = false }; };
template <> struct proxy<rhs> { enum { type = true }; };
enum { type = proxy<lhs>::type };
};
は、explicit specialization in non-namespace scopeエラーとなりコンパイルできません。
そこで、proxyクラステンプレートをnamespaceスコープで特殊化することになりますが
この書き方がサッパリわかりません。
外側のクラステンプレートは特殊化せず、内側だけを特殊化したいのです。
コンパイラはgcc-3.3.3です。
>>990 それはbind使う意味があるんでしょうか?
>>991 bind内部では参照がメインだからです。
boost::bind( &std::for_each<std::vector<int>::iterator&, func>, _1, _2, _3)( v.begin(), v.end(), func());
これでいいと思うよ。
994 :
デフォルトの名無しさん :2005/07/01(金) 08:04:40
>>993 やってみて駄目だったんですが、
一時オブジェクトは非const参照には変換出来ないとわかりまして
以下のようにしたら通りました。
勉強になりました、ありがとうございました。
std::vector< int > v;
std::vector< int >::iterator b= v.begin();
std::vector< int >::iterator e= v.end();
boost::bind( &std::for_each< std::vector< int >::iterator, func >, _1, _2, _3)( b, e, func());
>>992 for( iterator i = v.begin(); i != v.end(); ++i){
for( iterator j = i->w.begin(); j != i->w.end(); ++j){
func( *j );}}
これを関数オブジェクトで書けないかと検討中だったんです。
しかし、bindやlambdaというのは使い道が見えません。
普通に直で関数オブジェクト書いちゃった方が楽な気がする・・
996 :
デフォルトの名無しさん :2005/07/01(金) 10:59:36
@string型をint型にキャストするにはどーすればいいんですか?? StrToIntとかToIntという関数があるようですが, これでは駄目なようで困っています. Aファイルから1行を切り出すにはどうすればいいんですか?? 40文字ずつ改行しながら別のファイルに出力させていくという プログラムを作りたいのですが, char *c; fileReader.get(c, number, '\n'); のようにしてnumberが21くらいになるとメモリがreadにならないという エラーメッセージが出てきます.どうしてでしょうか??
>>996 inline int stoi(const string& str) { return atoi(str.c_str()); };
関数名から予想するとBCBのようだけど、
AnsiString == String != std::string (!= CString)
なので注意ナ
「一行」切り出すのは、finをテキストモードで開いて
string str;
getline(fin, str);
40文字ずつ改行するならsubstrかカウンタ使う
漏れならperl使う
>>992 >型AとBが同じ型のときtrueを、異なる型のときfalseを返すクラステンプレート
これだけが必要なら別に外側だけ特殊化すればよいような気がします.
>外側のクラステンプレートは特殊化せず、内側だけを特殊化したいのです。
これは言語規格的に無理です.
999
ギリギリまで真面目に話してるおまえらにもえ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。