【初心者歓迎】C/C++室 Ver.67【環境依存OK】
janeの隠し機能 1.書き込みウィンドウを出し半角入力に切り替える 2.Wキーを押しっぱなしにする 3.Wキを押しっぱなしにしながらsageのチェックするところをおもむろにクリック
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
ERROR! ERROR:長すぎる行があります!
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
前スレの933ですがプログラムの問題ではなくscimの問題だったみたいで解決しました
std::mapとtr1::unordered_mapって 速さ:std < tr1 メモリ節約:tr1 < std でおk?
11 :
デフォルトの名無しさん :2009/07/19(日) 22:08:40
>>10 あー、一般論としてはそんな感じになると思う
12 :
デフォルトの名無しさん :2009/07/20(月) 23:31:44
class CardSet { public: CardSet() {make();}; //CardSet() {}; void make() {}; }; class Player { public: Player(){}; ~Player(); }; class SubPlayer : public Player { public: CardSet a; SubPlayer() {}; }; main(){ Player * a = new SubPlayer(); } このプログラムをg++ 3.4.3 32bit Linuxでコンパイルすると、 In function `SubPlayer::SubPlayer()': undefined reference to `Player::~Player()' というエラーになります。しかし、CardSetのコンストラクタを コメントアウトしている方に切り替えると、エラーなくコンパイルできます。 ~Player()を定義すれば済む話ですが、なぜこのような違いが起こるのでしょうか?
13 :
デフォルトの名無しさん :2009/07/20(月) 23:45:15
固定小数点同士の乗算がしたいのですが 掛けたらオーバーフローになってしまうのでどうしたらいいのかわかりません 今は片方を普通の小数にしてやっちゃってますが意味がない気がするし 整数と小数をわけて乗算するしかないのでしょうか それだとあまり意味がないのでしょうか
>>13 32bit×32bitは64bitになる。これあたりまえの話ね。
だからアセンブリ言語では大抵、整数乗算命令は上半分と下半分を別々に取得することが出来るようになっている。
C言語の枠内では(__asmとかintrinisic関数とか使わない限り)効率的な方法は存在しない。
シフトしながら足し算していこうかな、とか
32bitを16bit+16bitに分割して4回掛け算をやろうかな、程度。
>>14 もう1つある。最適化を期待するんだ。
int32_t x, y;
int64_t z;
という状況で、VCは最適化ありにすればz = (int64_t)x * y;をimul(32 bit * 32 bitの結果を64 bitで返す)1つにしてくれる。
よそのコンパイラもこれくらいやってくれるだろう。
ところで、
>>13 は固定小数点数同士を掛けた後、右シフトしていないだけのような気がする。
小数部Nビットの固定小数点数同士を掛けると、小数部が2Nビットの固定小数点数になるから、
小数部Nビットで結果が欲しいなら、Nビット右シフトが必要だぞ。
>>14-15 そういえばアセンブラとかだと二つのレジスタに入ったりしましたね
シフトは忘れていなかったんですが
掛けた時点で内部では32bitのままなのかなって思ったりしました
vc使ってるんですが64bit整数の型名知らないですが
((int64)a * b)
>>16 こんな感じに出来るのでしょうか
__int64かな。 long longも使えた気がする。
あ、型名入れてやったら出来ました ありがとうございました!
>>12 SubPlayer の生成中に、まず基底クラスである Player の構築が完了する、その後
メンバ変数である CardSet の構築が行われるが、この中の make() から例外が発生した場合、
すでに構築が完了した基底クラスを解体するため Player のデストラクタが呼ばれる。
CardSet のコンストラクタが空であれば、この途中で例外が発生しないことがコンパイラに
わかるので、 SubPlayer のコンストラクタで Player のデストラクタが必要になるフローがなくなる。
20 :
デフォルトの名無しさん :2009/07/21(火) 20:03:05
>>19 ありがとうございます。
そのような理由があったのですね。すっきりしました。
質問があります 完全に今から始める初心者なんですが、USB機器の例えばゲームパッド等からの入力を 例えば1のボタンを押したらキーボードのAに対応させるみたいに外部機器をキーボードの代わりにする みたいなことをしたいんですけどこういったのがこう言うのを作るのは難しいですか? それとこう言う物を作れるようになるための勉強の方法って猫でも分かる〜や、ゲームの作り方関係の本でも大丈夫でしょうか
>>21 OS上の動作全般に渡ってキーボード代わりとして使いたいのなら、
デバイスドライバを作成する必要がある。
Windowsの場合は、WDKでググれ。ただしほぼ断言していいが、初心者には無理。
自分のアプリだけでそうしたいのなら、ゲームパッドの入力ができればあとは簡単でしょ。
>>22 自分のアプリだけでって言うのは例えば自分の作ったゲーム内でのみ対応できる 見たいな感じでしょうか?
普通のキーボードじゃなくて別のものをキーボードにしたいんですよ
となるとデバイスドライバ云々って言う難しいほうになるのかな
そう言うのを作るにはどういった勉強したらいいか何か教本的な物ってありますか?
DirectInputとか
>>23 > 自分のアプリだけでって言うのは例えば自分の作ったゲーム内でのみ対応できる 見たいな感じでしょうか?
そのとおり。それでいいのなら別に難しいことではない。
キーボードだろうがキーボードじゃないものだろうが、そこはあまり関係ない。
SendKeysとか
>>23 それはつまり
>九九が分からないんですけど大学入試数学のいい参考書はありますか?
みたいなことを言ってるってことをとりあえず理解してね。
その上で九九から始める覚悟があるなら、
とりあえず「C言語の入門書」でも探してみればいいんじゃないかな
28 :
デフォルトの名無しさん :2009/07/22(水) 14:20:26
catchされない例外が投げられるときはデストラクタが呼ばれない なんてことありますか?
例外の細かい動作がいまだにわからない俺クリムゾンヴァイパー
31 :
デフォルトの名無しさん :2009/07/22(水) 14:23:43
そうか・・・ 確実に呼ばせるにはmainでcatch(...)するしかない?
exitとかabortとかすると呼ばれないと思うから確実には無理じゃないか
34 :
デフォルトの名無しさん :2009/07/22(水) 14:34:36
>>33 さすがにそれは保証外で
>>29 なんかソースあったら教えて下さい
デストラクタは例外投げられたときも呼ばれるという話ばかり見てきた気がする
new Object; throw -1;
処理系依存かー
ある初期化されたリファレンスがあったとして、ほかのインスタンスの参照を代入することはできないんでしょうか? int a(0), b(1); int& r(a); r=b; // aにbを代入ではなく、rにbの参照を渡したい
次スレからはメール禁止をテンプレに入れとけよ
それこそ金払ってやってもらえよ 専属の教師じゃねーんだぞ
factory methodってtemplateクラスに使う意味ってある?
Factoryの利点の一つはインプリメントとインタフェースを分離することだから templateでもその利点はあると思う。
cに限った話じゃないんだけどLinkedListってなんで線形リストって言うの? 連結リストでしょ?
Wikipediaによれば、線形リストは連結リストの分類のひとつらしいよ 両端を連結した循環リストは、線形リストでないっぽい
リストを管理してる先頭からしかたどれないのが線形リスト これに一方向だけでなく戻りもOKにしたのが双方向リスト ループするのが循環リスト これらの総称が連結リストでいいんでないの?
47 :
デフォルトの名無しさん :2009/07/23(木) 18:44:55
visual studio を使っているのですが、 一定間隔で処理する方法で困っています。 無限ループを作ってtimeGetTime()を使って時間待ちをして行っていますが、 GUIからのボタン操作を受け付けることができなくなってしまいました。 GUIのボタンを押して無限ループから抜けるためにはどうすればよいでしょうか? よろしくお願いします。 もしくは、もっとよい方法がありますか?
無限ループを作らず、タイマを使え
>>47 PeekMessage+GetMessage
50 :
47 :2009/07/23(木) 19:24:04
アドバイスありがとうございます。
>>48 タイマを使ってみたのですけど、
たとえば50ms周期で処理しようとすると60ms近辺が周期になって
しかも、40msとか70msとかばらつきも大きくてこれは使えないなぁと。
タイマの精度は1msだとwebで見たことありますが実際どうなんでしょう?
>>49 GetMessageを使えないかと思って、WINAPI関数の中の
GetMessageのところでブレークポイント設定したのですけど
ブレークできなくて、なぜなのかよく分かりませんでした。
ブレークできないなんてことあるんでしょうか?
while (GetMessage(&msg, NULL, 0, 0)) {
→ TranslateMessage(&msg);
DispatchMessage(&msg);
}
上の→のところでブレークしようとしたのですが・・・。
47の内容とは直接関係ないですけど、なぜなのだろうと思いまして。
51 :
デフォルトの名無しさん :2009/07/23(木) 19:29:08
二分木プログラムの問題で、二分木の高さと大きさを求める以外で、出そうな問題ってありますか?
別スレッド作ればいいなじゃないの
57 :
47 :2009/07/24(金) 11:50:59
無限ループの中でPeekMessageを使って GUIのボタン処理を受け取ろうと思ってやってみましたが、 GUIが固まってしまってボタンを押すことができませんでした。 どうすればよいでしょうか?
具体的なコードを
というか具体的な目的を
・処理スレッドを作成して、そこでループをぶん回す ・メッセージループでPeekMessageを使って、メッセージがない時に処理を実行して、適度に眠らせる のどちらか
61 :
47 :2009/07/24(金) 12:05:37
>>58 ソースを載せてみます。
BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
{
switch( msg ){
case WM_COMMAND: // ダイアログボックス内の何かが選択されたとき
switch( LOWORD( wp ) ){
case IDOK: // 「OK」ボタンが選択された
g_hDlg2 = CreateDialog( g_hInst2, _T("IDD_DIALOG2"), hDlg, DlgProc2 );
ShowWindow( g_hDlg2, SW_SHOW );
loop_flg = 1;
while(loop_flg){
if (PeekMessage (&msg_roop,g_hDlg2,0,0,PM_NOREMOVE)) {
ret =GetMessage (&msg_roop,g_hDlg2,0,0);
if(msg_roop.message == WM_COMMAND ){
if(msg_roop.wParam ==IDCANCEL) {
TranslateMessage(&msg_roop);
DispatchMessage(&msg_roop);
}}}
counter++;
}
case IDCANCEL: // 「キャンセル」ボタンが選択された
EndDialog( hDlg, 0 );
break;
}}}
ボタン宛のメッセージも回してやらないとボタン自身がマウスクリックを処理できない
63 :
47 :2009/07/24(金) 12:16:15
続き BOOL CALLBACK DlgProc2(HWND hDlg2, UINT msg, WPARAM wp, LPARAM lp) { switch( msg ){ case WM_COMMAND: // ダイアログボックス内の何かが選択されたとき switch( LOWORD( wp ) ){ case IDCANCEL: // 「キャンセル」ボタンが選択された // ダイアログボックスを消す loop_flg = 0; EndDialog( hDlg2, 0 ); fclose(fp); break; }}}
64 :
47 :2009/07/24(金) 12:23:55
>>62 ありがとうございます。
具体的にはどうすればよいのでしょう?
>>60 ・メッセージループでPeekMessageを使って、メッセージがない時に処理を実行して、適度に眠らせる
の亜種
MegWaitForMultipleObjectsEx で シグナルにならないダミーのハンドルを引数に渡す
# array が NULL で 個数0 の場合意図した動き(timeout付き GetMessage もどき)になるんだっけ?
PeekMessageやGetMessageで取得するウィンドウをg_hDlg2だけにしたり、 TranslateMessageやDispatchMessageするメッセージをWM_COMMAND/IDCANCELだけにするのをやめればよい
× MegWaitForMultipleObjectsEx ○ MsgWaitForMultipleObjectsEx
68 :
47 :2009/07/24(金) 18:23:51
>>66 さんの言うようにやったら
きちんと動作するようになりました。ありがとうございます。
どうして条件を指定すると動かなくなるのでしょう?
>>68 ウィンドウズのメッセージキューはスレッドに結びついてるんだ。
ある1つのスレッドが作ったウィンドウのメッセージは皆同じメッセージキューに入るんだ。
だからそのスレッドがほんの一部だけのメッセージしか処理しない状態だと、
その処理するメッセージ以外のGUI動作をしなくなる。
てのはC/C++でのウィンドウズプログラミングの基本なんだ。
猫でも〜辺りを一通りやった方がいい。
71 :
hey :2009/07/24(金) 19:03:31
nigga!
72 :
47 :2009/07/24(金) 21:17:11
猫でもは内容がかなり古いしな
質問があります、C/C++ と C++/CLIって全く別物なんでしょうか?
>>75 学習用途としては向かないんですね
ありがとうございました
>>72 expressでGUIをするなら、GUIフレームワークのライブラリを使うのもひとつの方法かな。
この版に単独スレのあるGUIフレームワークは、Qt、wxWidgets、WideStudioかな。
RADじゃないGUIフレームワークってデザインしにくくない?
>>78 >>77 のフレームワークにはRADツールは存在している。
フレームワークにはレイアウトを管理するクラスがあるからRADツール使わなくても慣れると簡単。
逆に画面デザイナを使うのが面倒になる。
初期化子つきの関数ポインタの定義の構文がわかりにくい なんでこんな構文にしたんだろう。
foo(*(*bar)(baz, hoge))(fuga)(piyo); とかぱっと見ようわからん typedefなしでもきれいに書ける仕様にすればよかったのに
括弧の数からしておかしいじゃねーか
どゆこと
うろ覚えで適当に書いたんだと思われ でもそんなに複雑かね int foo(int x, int y, int z) { return x + y + z; } int (*p)(int, int, int) = foo; こんだけだが
86 :
デフォルトの名無しさん :2009/07/25(土) 14:48:21
もっと初心者にもわかりやすくしてください
結局のところ宣言のところでカンマで区切ればint型だろうがint型のポインタだろうが書いて行ける仕様ゆえ 型の一部が分離しちゃうんだよね
中側から解読していくのが定石だな
>>86 foo(*(*bar)(baz, hoge))(fuga)(piyo);
baz型、hoge型の2引数をとり、(fuga型を引数をとり、foo型を返す関数ポインタ型)を返す関数ポインタ型の変数barを定義して同じ型のpiyoで初期化する
わかりにくいな
foo(fuga)(baz, hoge) bar = piyo;
とか書ければ楽なんだけど・・・なんでこんな複雑な構文にしたのかわからん
個人的にいらない仕様というかなんでわざわざアセンブラとかからステップアップした はずの言語でこんななの?と思ったのが? :の式
const double a = (b < 0) ? 0: b; ?:を使わずに書いてください。
>>90 boost::function を使うと簡単になるよ。
#include <boost/function.hpp>
using boost::function;
class foo{};
class baz{};
class hoge{};
class fuga{};
foo piyopiyo(fuga a)
{
return foo();
}
function<foo(fuga)> piyo(baz a,hoge b)
{
return &piyopiyo;
}
int _tmain(int argc, _TCHAR* argv[])
{
function<function<foo(fuga)>(baz,hoge)> bar=&piyo;
function<foo(fuga)> k=bar(baz(),hoge());
k(fuga());
return 0;
}
const double a = std::max(0,b);
うむw C/C++が混在してるなw
C/C++は1だし。
NaNかもしれないぞ
98 :
デフォルトの名無しさん :2009/07/25(土) 19:41:55
名前空間に定義されているクラスを他のクラスで使用するときに どうすればいいか教えてください。 (ヘッダファイル内) class String; class A { //... private: String* m_Name; } Aというクラスがあり、メンバーとしてString*を持たせるときは、上記のように class String;と書けばコンパイルが通ります。 もし、Stringが名前空間MyLibの中で定義されているときは、どのようにすればいいのでしょうか。 #include "String.h" とヘッダをインクルードするしかないのでしょうか。
namespace MyLib { class String; }
class A { //... private: MyLib::String* m_Name; }
実装のほうでtypedef
102 :
98 :2009/07/25(土) 20:51:57
>>99 ,100,101
ありがとうございます。
コンパイルが通りました。
C++でpptを読み込みを行いたいです スライドを画像にして読み込むにはVBAと連携させるしかないんでしょうか?
106 :
104 :2009/07/26(日) 17:00:08
ありがとうございます 今検索結果と同じようにVBAと連携させています。 pptのスライド画像はpowerpoint起動時に組み立てているようなので やはりVBAと連携が必須でしょうか? 後office2003,2007どちかが入っていれば動作するという動きにできるのでしょうか?
pptって仕様公開されてなかったっけ
#include <stdio.h> #include <windows.h> int main(void) { FILE *fp; char str[128]; fp = fopen("data.txt","r"); if (fp == NULL) { printf("data.txtが読み込めませんでした"); exit(1); } fclose(fp); fscanf(fp, "%s", str); printf("%s\n", str); return 0; } このように記述したのですがdata.txtの中身を正常に読み取れず、文字化けして出力されます。 data.txtの中身に何が書かれていようが、どうやら同じ意味不明な文字列が表示されるようです。 原因が掴めないのですが、どなたかご教示ください。
>>108 そのままだとファイルを正常にオープンできたとしてもすぐに閉じちゃってるよ
110 :
109 :2009/07/26(日) 17:55:48
#include <stdio.h> #include <windows.h> int main(void) { FILE *fp; char str[128]; fp = fopen("data.txt","r"); if (fp == NULL) { printf("data.txtが読み込めませんでした"); exit(1); } fscanf(fp, "%s", str); fclose(fp); printf("%s\n", str); return 0; }
なるほど… fopenした直後にfclose書いた方が忘れずに済むと思ったのですが、それではまずかったようですね… 正常に動作させることができました。 どうもありがとうございました。
ちゃんとマニュアルを読めよ・・・
>fopenした直後にfclose書いた方が忘れずに済む
おもしろい。
最初から開かなければ、絶対に忘れずに済むんだけど
そこまでは行かなかったのね。
で、一応まともなアドバイスだけど
fscanf(に限らずscanf系全て)は、必ず戻り値を確認するようにすべきだぞ。
そうしないと、入力が正常じゃなかった時にゴミが入っている。
>>108 のように。
114 :
104 :2009/07/26(日) 22:21:29
>>107 公開はされているようですがスライドを画像にすることはできないかと・・・
officeどちらかがインストールされていれば動くようにはできないのでしょうか?
公開されてるのなら、その仕様に沿って自分でスライドをビットマップ上に描画すればいいのでは・・・ まぁ手間だろうからあんまりやりたくないんだろうけど。
だから、VBAで出来ることは全てC++からのOLEオートメーションで出来るっての。 あなたに出来るかどうかは別として。
VBAでは画像としての取得ができているんだよな。 だったらそれをC++に書き換えるだけ。 #importなりなんなりすれば、VBAで使われるオブジェクトモデル (メソッド・プロパティ・型名・定数など)はほぼそのままC++でも使用可能。 g++とかのタイプライブラリ読み込みの#importが使えない処理系なら話はもう少し面倒だけど。
118 :
104 :2009/07/26(日) 22:58:30
ビットマップ描写はちょっと自分では難しそうです C++から呼び出して出力できるようにはなっています officeのバージョンが違っても同じように動作してほしかったんです OLEオートメーションでもう少し調べてみます ありがとうございました
ビットマップは簡単だよ ヘッダ+2次元配列だから
>>118 画像にするのは簡単だよ。名前を付けて保存をすればいい。
PowerPointではBMPやEMF、あるいはJPEG、PNGなんかで保存できる。
それをVBAやC++で呼び出すだけ。
バージョンを問わず動くようにするには、オブジェクト作成時にバージョン指定せず、
その後も遅延バインドにする。
VBAではObject型、C++ではIDispatchPtr (IDispatch)を使う。2つは同じ。
IDispatchを直接叩くのはやや面倒だろうが、
これくらいなら適当にラップすればなんとかなるだろう。
&& と || はあるのに、 ^^ がないのはなんで?
何に使うの?
XOR条件にしたいのか そいつは無理だ 知っての通り条件式は短絡評価をしているが XOR条件を実現するには短絡評価を捨てなければならない
あ、ちなみにXOR条件は次のようにしてエミュレートできる i = cond1; j = cond2; i ^ j; この例を見てもわかるようにXOR条件は短絡評価ではなく 両者のブール値を必ず評価しなければならない
i != j;
(cond1 && !cond2) || (!cond1 && cond2)
>>126 それだとcond1が二回評価されてしまうから>124とは違ってしまう。
!i != !j
>>120 レスありがとうございます。
わからない単語だらけですがぐぐってがんばります
クラスでメンバ変数を定義した場合、どうやってアドレスを取るのでしょうか
&de
そうですね
>>132 最大で1/(40000*2)秒ずれうるから、元の音が再現できてるとは言えないって言ってるのかなぁ
>>134 単純に倍だとタイミングがあってればいいけど合わない場合は元の音にはならないね
倍より大目のサンプリングが無いと
>>132 振幅が一定の永遠に続く20KHzのサイン波なら40kHzのサンプリングで再現できる。
20KHzの信号でも、ひずんでいたり振幅が変わったり変動する場合は20KHz以上の
成分が含まれているから、40KHzのサンプリングでは再現できない。
例えば大まかにでも波形を再現するには3倍以上の周波数成分が欲しいかな。
すると120KHz以上でサンプリングする必要がある。
もっと正確に再現するにはもっと高いサンプリング周波数が必要になる。
シャノンは「20kHzを再現するには少なくとも40KHzのサンプル数が必要」 と言っているのであって、サンプリングできるなんて一言も言ってない。
必要条件だが、必要十分条件ではないということ?
その辺の話はダウンサンプリングとかでも解説されてるよ
サイン波の最大値と最小値のところでサンプリングできればいいが 0のところでサンプリングしたら無音になっちゃったりするの?
無音というか変な音が出る可能性もある だからサンプリングする場合はオーバーサンプリング気味にして丁度いいくらい
どうあがいてもデジタル化した時点で劣化するってことか
>>143 そりゃ量子化の段階でカクカクになってるしねw
しかもサンプリングレート次第ではさらに飛び飛びだし
自分で方眼紙に適当な波形を書いてマスを数えてみればいい
かくかくもそうだけど一定の周波数の音でさえも、画像で言うところのモアレみたいなのが発生するってことだよね 大変すなぁ
>>146 大丈夫、大抵の人はそのモアレを聞き取れない。
>>147 聞き取れないはずの高調波がサンプリングによって
可聴範囲のノイズとして現れることはあるんじゃね?
非常に高い周波数だけど、サンプリング点を繋げるとゆ
るやかなサインカーブ、という嘘データは作れそうだし。
>>136 まてや。
20kHzの振幅が変動する波は20kHzより高い周波数成分を含んどるやんけ。
サンプリング定理は、その含んでいる最高の周波数成分の2倍でサンプリングしろということじゃ
>>147 それいっちゃったらカクカクについても聞き取れないから大丈夫ってことになっちゃうし
class hoge { public typedef bool Bool; public: Bool fuga(); }; Bool hoge::fuga() {return true;} これって普通コンパイルできないと思うんですが なんかできてしまうことがある・・・これはvc++が変だからでしょうかね? バグなのかな・・・?
>>151 それでコンパイル通るんだったら根本的に壊れてるんだと思うが?
上のコードでは通らないんですが下のコードならvc++ee2008で通りました #include <iostream> namespace hoge {     class hoge {     public:         typedef bool Bool;     public:         Bool foo();         Bool bar();     }; } namespace hoge {     hoge::Bool hoge::foo() try {return true;} catch(...) {}     Bool hoge::bar() {return true;} // <- ! } int main() {     hoge::hoge h;     if(h.foo()) std::cout << "foo" << std::endl;     if(h.bar()) std::cout << "bar" << std::endl;     return 0; }
::hoge::Boolがなぜ見えるのかってこと? ::hoge::hoge::Boolではなくて
hoge::Bool hoge::foo() try {return true;} catch(...) {}
ちなみにこれをコメントアウトするとコンパイルできなくなります
>>154 Boolはhogeの中限定なのでhoge::Boolにしないと外からは見えないからですよね?
>>155 そうです
hoge::Boolは外からは見ると存在しないはずなのに・・・
WindowsのGUI関連の質問なんですが、コントロールの描画に手を加えたいときは、オーナドローとサブクラス化の 手段が考えられますが、どちらの方が一般的なのでしょうか。 あるいはどちらの方が負担の軽い処理となるのでしょうか。
>>157 サブクラス化してオーナードローすればいいんじゃね?
オーナードローが開かれた〜♪
>>151 hoge内の他にグローバルでtypedef bool Bool;されてたり
>>153 こちらでもVC++EE2008で試して、通ることを確認した。
function-try-blockの直後は、まだclass hogeのスコープが残ってしまっている雰囲気だね。
他にも、コンストラクタのfunction-try-blockのcatch内でreturnしてもコンパイルエラーにならないし…。
この辺、VCは何かおかしい。
>>160 それは無かった。
>>159 きらめく光俺〜を〜うつ♪
か。 ちょっと一瞬判らなかったよ。
パパラッパパラッパーラー
ワラタ ダンバインか
変数の参照関係(?)で質問です。 waitを呼び出したとき、for文で無限ループになります。 現状自分で確認できたのは次の通りです。 1.timer_procは1秒毎に呼び出されている(LEDの点灯/消灯コードをいれて確認) 2.wait内のfor文の前でLED点灯のコードを入れ、LEDが点灯できた 3.wait内のfor文の後でLED点灯のコードを入れ、LEDが点灯されない 変数の宣言と定義などで何か勘違いしていてtimer値がおかしい結果になってると 思うのですが、どう修正すればいいか教えてください。 ソースはこんな感じです。 ----- a.c ----- #include "a.h" int timer; /* 1秒に1回割り込みで呼び出される */ void timer_proc(void) { if (timer > 0) timer--; } ----- a.h ----- extern int timer; ----- b.c ----- #include "a.h" void wait(void) { for (timer = 10; timer; ) ; }
timerにvolatileを付けたらどうだろう。
>>165 処理系がわからんからエスパーするけど
forのなかのtimerが最適化されて定数に置き換えられてるんじゃないの?
volatileつけてみるとかいうのはどうだろう
君たちは結婚すればいい
169 :
165 :2009/07/30(木) 22:27:56
継承ってのは大抵public継承にするのが一般的なんですかね
場合による
public→ベースにできることは派生で全部できる時に使う private→実装がほしいだけの時に使う。でも実装がほしい場合は普通メンバ変数として持たせる
stateパターンの利点がいまいち分からないんですが。 switch(state){ case STATE_1: state_1(); break; case STATE_2: state_2(); break; } これが、 switch(state){ case STATE_1: obj = state_1; break; case STATE_2: obj = state_2; break; } obj.func(); になるだけでstateパターンを適用することでif~else()かswitchを使った 状態遷移処理は消えなくないですか
初期化が obj = state_1; とかで、後は obj->func(); を回すだけ 遷移はstate_1の中で obj = state_2; とかやる switchなど不要
obj->func() の戻りが obj になってりゃ良いんでないの? obj = state_1; // 初期ステート obj = obj.func(); // ステート変遷
各状態が全ての状態のオブジェクトへのポインタを持つってこと?deleteはいつやるの?わかんなくなってきたぞ。。
遷移するときに obj = new state_2; delete this; とかでもいいし 何も考えず全部グローバルでもいいし お好きにどうぞ
各状態を全てシングルトンにして、 初期化で IState* state = STATE_1::getObj(); ループで state = state->func(); にしてfunc()内で、 return thisとか return STATE_2::getObj(); とかしてスッキリになりました状態遷移処理だけでなく状態管理変数も不要になるんですねありがとうございました。
>>178 あまりその辺を突っ込むとタスクシステム大好きおじさんが来るから気をつけてねw
明快入門 Visual C++ 2008 ビギナー編って本が分かりやすいけど 知識0の全く最初からVC++の機能をフルに使って勉強してると環境が変わったら何もできなくなりそうで怖い 分かりやすいけど・・・
windows以外でやらないなら問題ないw >180
オレ様基準で皆がコンパイルエラー出すようなコード書く前提で威張ってもらっちゃ心外だな
>>180 VSの機能をフルにつかえてるなら、makeやらをちょろっと書けるレベルよりはるかに上。
>>181 そりゃそうだけどw
趣味でやるならwindows環境だけでやれるけど、もしも仕事にするなら多分win以外の環境も多いんだろうなあと思ってさ
>>183 本当にフルに使えてるなら結構凄いのか
Cでアドイン書いて自分で拡張できるわけだから そりゃ凄いことができると思うよ やりにくい処理は他の処理系に投げることもできるしね
知識0の全く最初からフルに使える人なんているとは思わなかった
Cをすっ飛ばして最初からC++が学べる本ってありますか?
accelerated C++
>>188 私に対するレスです・・・よね?
その本はC++から学ぶ事を目的とした本なんですか?
本関係ないけどC++の成分の7割くらいはCだと思うんだ。 C++"だけ"を学ぶってのは無理じゃないの? C++とCから一部省いたものを同時に学ぶだけで。
C++があればまず使わないようなやり方を学ぶ手間は省ける
でCの入門書の場合、その類の事に対する説明の割合が大きい
そういうのをすっとばしてC++流のやり方がてっとり早く学べる本の定番が
>>188
入門書でスマートポインタまで教えてくれる本はなかなかないからね。 Accelerated C++は名著。超高密度。
メンバ変数の多次元配列をコンストラクタで初期化する場合はfor文で回すしかないですか
下記質問をboostすれで聞いたら、 --------------- boostのpoolを使いたいのですが。class内のメンバ変数に指定する方法がわかりません。 boost::pool<> p(sizeof(int)); この行を、グローバルやローカル変数にすると問題がないのですが。 class AA { boost::pool<> p(sizeof(int)); } クラス内に入れるとコンパイルエラーになってしまいます。対処方法がないでしょうか --------------- 「C++の基礎からやり直せ 」の回答が来ました。どうも初心者の質問のようでした。 なので、初心者スレでお聞きいたします。よろしければ何かアドバイスをください。 注)代理で書き込みをお願いしているので、返事が遅くなる可能性があります。
boostの前に、C++のクラスを一つでも作成したことあるの? クラス定義で初期化はできないよ
ただし、const staticな整数型は例外。
>>196 最近それに気付いたんだけど、昔からそうだった?
unicodeの文字列から漢字かどうかって判別できますか?
>>200 漢字の領域が定義されているからそれで判断すれば
あ、 rational さん。
>>200 半角文字に変換する関数で変換できなければ漢字として扱えばいいだけ。
この程度を瞬時に思いつかないようなら仕事はない。
と、派遣を首になった無職がわめいております。GetStringTypeEX。
オレのマシンでは GetStringTypeEX なんて使えないぞ
>>203 半角に変換できない文字⊂漢字だが、
半角に変換できない文字=漢字ではない。
漢字⊂半角に変換できない文字だった
>>203 そっか。。だからうちの会社仕事減ってきてるんだな。。。
はやいやすいまずいは中国の専売特許だからやりたくないけど不況を乗り切るためには仕方ないのかなぁ
今のご時世、どこも一緒(´〜`)
プログラム作るよりパソコン教室とか開いて教えたほうが楽だよ
>>203 半角ハングルというのがあってだな・・・
213 :
212 :2009/08/06(木) 11:47:47
ごめん、なんか勘違いしてた。 無視してくれ。
チョンコは(・∀・)カエレ!!
下のソースで class CVec { std::vector<int> vInt ; public: void Get(int *pInt) { vInt.push_back(5) ; pInt = &vInt[0] ; } }vec; int _tmain(int argc, _TCHAR* argv[]) { int* pInt = NULL ; vec.Get( pInt ) ; return 0; } mainのとこでpIntにアドレスを戻す事が出来ません こういうことは出来ないんでしょうか?
void Get(int *pInt) → void Get(int *&pInt)
出来ました有難うございました
>>215 その戻したポインタはクラス内部でvectorに対して変更を掛けたら無効になるから要注意。
つーか、const_iteratorを返す方がよかないか?
flvのプレイヤー作るにはなに勉強すればいいですか??
FLEXだと手軽にできるかな 体験版でプレイヤー作ったけど期限切れでそのまま放置してるの思い出した
222 :
219 :2009/08/08(土) 02:19:02
>>220 C++からでもflex使えるんですか 調べてみます
>>221 ありがとうございます!参考にしてみます
型の等しい二つの関数、例えば int foo( int ); と int bar( int ) への共通のポインタは int (*)( int ) で得られますが、 関数としての型は等しいが異なるクラスのメンバである関数、例えば int Widget::foo( int ) と int gadget::bar( int ) への共通のポインタは 得られないものなんでしょうか。 普通に考えると前者は int ( Widget::* )( int )型、 後者は int ( gadget::* )( int ) 型で型が違うので無理なような気もしますが 普通でなくなりたいのです。 例えば class Gadget : public Widget; のようにして ポリモーフィズムを利用してなんとかできないかなとか思ったんですが Visual C++は許してくれませんでした。
>>223 いや、継承関係にあれば問題ないはず。
エラーメッセージと、できれば実際のコードを貼ってみることだね。
うそ言うな
それが出来ないというのが BCBで__closureという独自拡張がなされた理由の一つ。 継承関係があっても、別クラスのメンバ関数のポインタは、異なる型。
224は間違っていないぞ。 GadgetがWidgetの派生クラスなら、Widget::*なメンバへのポインタはGadget::*なメンバへのポインタに変換できる。 なぜなら、Gadgetのインスタンスは当然Widgetのメンバを持っているため。 #include <iostream> struct Widget { int foo(int) {return 1;} }; struct Gadget : Widget { int bar(int) {return 2;} }; int main() { int (Gadget::*p)(int) = &Widget::foo; Gadget g; std::cout << (g.*p)(0) << std::endl; // 1 } もちろん、上のpはint (Gadget::*)(int)型なので、Widget w;があったとして、(w.*p)(0)のような使用はエラーになる。
BCBの__closureみたいなことがやりたければ、一般にはfunctionとbindで実現できる。 Gadget g; boost::function<int (int)> f(boost::bind(&Widget::foo, g, _1)); std::cout << f(0) << std::endl; こっちの方法では、もう継承関係とか不要。
今、C言語の勉強をしていて、Visual Studio 2008で書いてるんですが、 xに代入した乱数を配列aに一文字ずつコピーしたくて、 int x,y,z; int a[5]; srand(time(NULL)); x = 1000 + rand() % 9999; y = x; z = 5; do{ --z; a[z] = y % 10; y = y / 10; }while(z >= 0); printf("乱数の数:%d\n",x) printf("配列の数:%d\n",a) などと書いたんですが、配列の方の数がどうしても合いません。 というか乱数を代入してるのに同じ数字しか表示されません。何がいけないんでしょうか?
> a[z] = y % 10; ここで添え字を使えているのに、なぜprintfのほうではできてないのだ
使い方は間違えてなくね 一秒以内に複数回実行した場合は同じ乱数が生成されるだけ
srand(time(NULL)); パッと見、これにはそんなに違和感は感じない。 printf("配列の数:%d\n",a) ここは明らかにおかしいが。
printf("配列の数:"); int i = 0; do{ printf("d%",a[i]); i++; }while(a[i] > 0); としてみたら、正常に表示されました。ありがとうございました。
235 :
229 :2009/08/10(月) 22:10:55
for文を使わないのは何か理由があるのか?
>>234 > }while(a[i] > 0);
これ配列の最後を超えてa[5]にアクセスしてるだろ
つーか、a[i]ってどこかで初期化しているの?
i が 0から4 を舐める間で さらに a[i] が 0以下だったら中断 こういう意図だと思うが… やはり何故 for を使わないのか疑問だ
まだ習ってないとかじゃね?>forを使わない
C++で、 %演算子の結果は 正の数%正の数 以外は処理系定義でしょうか?
242 :
241 :2009/08/12(水) 14:17:52
BohYoh.com−C/C++ FAQ 負数に対する除算の結果がおかしいのはどうしてですか。
ttp://www.bohyoh.com/CandCPP/FAQ/FAQ00134.html こんなところを見つけました。
ということは、
int hoge = 何とか;
が
... -6, -4, -2, 0, 2, 4, 6, ...
といった偶数であるかどうかは
<方法A>
std::abs(hoge)%2 == 0
<方法B>
hoge%2 == 0
のどちらでも大丈夫と言うことでしょうか?
それとも<方法B>は余りが2になって返る可能性がありますか?
>>242 剰余の符号は処理系定義だけれど、剰余であることが保障されるので2になることはない。
方法Bで十分です 余りが2になることはないです その余りを考えた場合(2 % 2 == 0)になるからです
245 :
242 :2009/08/12(水) 14:25:03
では<方法B>にさせていただきます。 ありがとうございました。
ちなみに有効なint型であることが保証されている変数hogeが 偶数であることの判定は一番速い方法は何があるだろう? bit演算かな?
>>246 処理系、実行系依存。条件を限定しない限り、速度比較は無意味。
248 :
246 :2009/08/12(水) 18:01:25
>>247 やっぱそうだよね。
得意不得意あるだろうしなぁ。
ありがと。
一般的に除算、剰余は高コスト %2はコンパイラが何か最適化するかもしれんけど。
int main(int argc, char ** argv) { // mod 2 チェック w/ gcc -S -O3 foo.c @gcc 3.4.4 #if 1 printf("%d\n", argc % 2); // movl 8(%ebp), %ebx // movl %ebx, %edx // shrl $31, %edx // leal (%ebx,%edx), %eax // andl $-2, %eax // subl %eax, %ebx // movl %ebx, 4(%esp) #elif 0 printf("%d\n", argc & 1); // movl 8(%ebp), %ebx // andl $1, %ebx // movl %ebx, 4(%esp) #elif 0 printf("%d\n", argc - (argc / 2) * 2); // argc % 2と同じなので割愛 #else printf("%d\n", (argc % 2) != 0); // xorl %eax, %eax // testb $1, 8(%ebp) // setne %al // movl %eax, 4(%esp) #endif return 0; }
// andl $-2, %eax // subl %eax, %ebx これか 久々のアセンブラなんで外れかも eaxってことはx86 32bitかね?
252 :
250 :2009/08/13(木) 09:58:03
// こちらはunsigned版。 int main(unsigned argc, char ** argv) { // mod 2 チェック w/ gcc -S -O3 foo.c @gcc 3.4.4 #if 0 printf("%d\n", argc % 2); // movl 8(%ebp), %ebx // andl $1, %ebx // movl %ebx, 4(%esp) #elif 0 printf("%d\n", argc & 1); // argc % 2と同じなので割愛 #elif 0 printf("%d\n", argc - (argc / 2) * 2); // argc % 2と同じなので割愛 #else printf("%d\n", (argc % 2) != 0); // xorl %eax, %eax // testb $1, 8(%ebp) // setne %al // movl %eax, 4(%esp) #endif return 0; } #if 0 結論。 ・符号付整数型の場合、2で割った余りが0, 1, -1の3値になりうるので% 2では最適化しにくい。 ・必要なのは0かそれ以外なので% 2した結果を0と比較することで、& 1にまで最適化される。 ・符号なし整数型の場合は、% 2でも& 1にまで最適化される。 #endif
253 :
250 :2009/08/13(木) 10:02:23
おっと、リロードしなかった。
>>251 x86ですよ。それもcygwin。
整数型として評価させているのでこういう結果ですが、条件分岐に使うと又違うかもしれませんね。
まぁ私は% 2派ですが。
eMbedded Visual C++ 4.0について質問です。 DLLを作成し、exeでビルドするとLNK2019でリンクエラーになります。 対処方法を教えてください。 以下、詳細です。 プロジェクト作成ウィザードで「WCE MFC AppWizard(dll)」をデフォルトのまま作成し、そのままビルド。 次に「WCE MFC AppWizard (exe)」もデフォルトで作成し、 DLLの.hをexeの.cppにincludeし、プロジェクト設定でdllの.libをリンクしました。 これだけの状態ですが、exeでLNK2019が発生します。 exe側の処理はDLLのクラスを宣言しているだけで、コンストラクタだけの状態です。 MFCなしのDLLでは問題なくexeがリンクできます。 作りたいのはMFCが利用可能なクラスDLLです。 設定の問題か、WCE MFC AppWizard (dll)で別の記述が必要なのかが判断つきません。 以上です。
質問です。 テキスト文字列で (5 + 8) * 3 のようなものの答えを計算するライブラリというもので、何かスタンダードなものはあるでしょうか? 自作もいいのですが、正規表現ライブラリのBoost Regexのように何かしら既存のものがあればと思いまして。
system("awk 'BEGIN {print (5+8)*3}'") 結果を回収したいならpopen("awk 'BEGIN {print (5+8)*3}'", "r")してfgets()で。
えーと、なるべくなら内部に組み込みたいのですがどうでしょうか? 使い方としては、 ゲームのパラメータを外部のtxtに持たせてまして、今はそこに数値のみかけるのですが、 これを計算式までかけるといいなと思いまして。 level = 10 sytem = 20 power = level * 5 とかできるといいなと思っています。 プログラム中からは、文字列の"level"などをキーにして、設定されている数値を取得しています。 (余談ですが、map<string, int>を使っています)
>>255 Boost.Regex のようにって言うなら、 Boost.Spirit の出番じゃないか?
>>257 えー、外部の方が楽できるよw
awk 'BEGIN {level = 10; system = 20; power = level * 5; printf("level:%d\nsystem:%d\npower:%d\n", level, system, power);}'
とかw
awk教徒は質問者を混乱させるだけだから帰れよ
早速Spiritを調べてみました。 面白いですね。 ちょっと解説ページみながらこねくり回してみたいと思います。 ありがとうございました。
数式 解析 C++ でぐぐれよ
複数のDLLをロードするときに、 ロードが成功したものをvector<HANDLE>にpush_backで入れると、 HANDLEのアドレスが被ってうまくいかないようです。 for(・・・){ HANDLE hd = LoadLibrary(・・・); v.push_back(hd); } v[0]とv[3]が同じ値になったりします。どうしたら良いですか
267 :
266 :2009/08/14(金) 15:07:07
hdが消滅するのが駄目と思いますが、newで確保してそのポインタをvectorに入れたらいいですか? newは一貫して使いたくないのですが、回避する方法ありますか?
これだと重複しませんでした。 HANDLEと関数を束ねたクラスを用意し クラスの中でクラスを使ったりするのが失敗の基の気はします。 HANDLEのコピーをしていくうちに、メモリリークと同じような事が起こっている気はします。 確定ではないですが。 vector<HANDLE> hd; for(・・・) { n=hd.size(); hd.resize(n+1); hd[n] = LoadLibrary( ・・・); }
これだとHANDLEが重複します。 DLLdataは HANDLEと関数のクラスです。 原因わかりますか? 268とほとんど変わらないと思いますが vector<DLLdata> x; for(・・・) { n=x.size(); x.resize(n+1); x[n].hd = LoadLibrary( ・・・); }
push_back()を使わないのは何か高邁な思想でもあるのだろうか。
>>270 push_backと ・・・ = LoadLibrary( ・・・)では値の入れられ方に違いがあるのでは?
と思いました。 でも原因は別にあるようです。 特定できていません。
原因わからないので、vector<クラス>を止めて回避する事にします。
>>269 vectorのresize時にデストラクタが呼ばれるのは知ってる?
DLLdataのデストラクタで何かやってないかい?
デストラクタでは、FreeLibraryをやってます。これが駄目な原因ですか。 使い終わったら解放するのが普通ですが。
vectorはリサイズ時にメモリを確保し直してオブジェクトを移動することがある その場合vectorはコピーコンストラクタを呼んで新しい位置にオブジェクトをコピーし 古いオブジェクトをデストラクタで消す
原因はわかりました。 DLLdataのデストラクタを外すのは、他所への影響もあるので そこだけ、 vector<HANDLE> vector<関数1> vector<関数2>・・・と分けて定義する事にしました。
HANDLEはHMODULE(long int)か?
だとすればただの値のコピーであるものが
>>266 で重複するというのは
同じパスのDLLを二回以上ロードしてるだけって気がするんだけど
HANDLEもユーザ定義の型だったりするのだろうか
そういやpush_backもだな push_backに渡した引数は、vectorのメモリ領域にコピーコンストラクタでコピーされて、 渡した引数自体はデストラクタで破棄される 要するに、適切なコピーコンストラクタを書かなきゃだめということ
コンテナに値セマンティクスのないオブジェクトを入れちゃダメって メイヤーズ先生もサッター先生もマッサー先生も あれほど口をすっぱくしていってたじゃないか。 忘れちゃったのかい?^^
すみません
>>266 は確かめて無くて。
たとえのような物でした・
重複してないかもしれません
>>265 お前こそぐぐれよ
それでぐぐってもspritはでてこねーよ
何ページもめくれば別かもしれんが
>>280 たとえのような物ってどういう意味だよ。
>>266 は明らかに質問の前提となる現象として書いてるじゃないか。
Win32APIのLoadLibrary関数の話なら戻り値はvoid*型だから
>>266 のコードでまったく問題なく動くよ。
重複も起こらない。今試したから間違いない。
だからエラーは
>>266 のコードが原因じゃない。
目標は達成しましたよ。 トンクス Susieライブラリで多種画像を読み込めるようにしたかったんです。
285 :
デフォルトの名無しさん :2009/08/15(土) 20:30:33
c++のクラス変数に初期値を与えるにはコンストラクタで代入しないと駄目ですか?
ダメだね。
いっぱいあると面倒ですねありがとー
>>285 代入じゃない。初期化リストで初期化するんだ。
289 :
デフォルトの名無しさん :2009/08/15(土) 22:53:54
何をだって?
自分で好き勝手に組めばよろし
292 :
デフォルトの名無しさん :2009/08/16(日) 01:50:54
for文とwhile文はどっちのほうが速いんですか? VC++使ってます。
do-while と goto が一番速いからそれ使え。
>>292 速度は実測が基本。
比べてみればいい。
比較するコードの骨子をこのスレに晒して見ればいい ループ云々以前の問題で小突き回されるだろうからイイ勉強になるぜ
do-whileを使う状況ってほとんどなくね? 俺はほとんど使ったこと無いんだけど。
if (cond) { prepare(); do { work(); } while (cond); }
>>296 ミスって無限ループされたら嫌なんで基本的に使ってない。
メッセージループとかは別だけど。無限ループって怖くね?
一度実行しないと反復条件が確定しない状況とかたまにあるだろ
300 :
296 :2009/08/16(日) 12:20:44
>>299 俺もたまにはある。
だから「たまに」使う。
でもforやwhileと比べて出番の頻度は相当低いな。
Primitive Loop Structures Must Go
括弧のくくり忘れとか(間違って余計に}を削除しちゃったとか)の時に、 doとwhileの個数数えると問題箇所がすぐ分かるからよく使ってる俺は異端ですか?
303 :
300 :2009/08/16(日) 16:42:26
>>302 そんな工夫初めて知ったわ。
ちゃんとインデントしていればだいたい分かるじゃん。
あるいはIDE/エディタの機能でも対応するカッコくらいわかるじゃん。
まあいいけど。
最近はforを直接使う頻度が減ってきた
ふぉー書くのってめんどいよねぇ。 なるべくforeachで済ませたい
>>305 foreachなくね?
boostの実装を使うって事?
boostとかCLIとか自前マクロとか
STLのfor_eachのことだったりして^^
あれは却って記述量が増えて悲しくなるケースが多い
310 :
デフォルトの名無しさん :2009/08/16(日) 17:57:36
他人のソースに、 void* Hoge::operator new(size_t size){ return reinterpret_cast<Hoge*>(new char[sizeof(Hoge)]); } みたいなnewの仕方があったのですが、 普通のnewと比べても速度があまり変わりません。 こういう書き方は何のためにやってるのでしょうか?
独自のアロケータを使う場合とか
ち、違うんだからね! charの配列を作りたいんじゃないんだからね! あくまでHogeのために領域確保したんだから そんなココロ
>>303 いや、インデントしてんだけど、mainの}、ifの}とかで挟まれて階層が複雑化していくと、
while文やfor文だと全部同じ } だから分かりにくく・・・。
対応する { } は、その間の背景色を変更してくれる色分け機能とかあったらいいなぁ。
Visual Studio 2008 Professional Edition使ってるんだけど、まだ始めたばかりだから機能なんて全然分からないぜ・・・。
>>310 そのコードじゃ意味ないんで、たぶんその人は何か勘違いしてる。
最近知った C++ の機能をちょっと使ってみたかっただけとか、あると思います。
コンストラクタを呼ばないという意味がある
new演算子とoperator newは別なので オーバーロードしてあっても、 newを使って確保すれば、やっぱりコンストラクタは呼ばれます。 newを使わずスタックに確保しても、当然呼ばれます。 別途確保した領域にplacement newを使えば呼ばずに済みますが operator newをオーバーロードしたこととは全く無関係です。
317 :
303 :2009/08/16(日) 21:14:35
>>313 まあインデントはしてるだろうとは思ってたが。
インデントしない方が無理だしw
318 :
303 :2009/08/16(日) 21:16:42
>>313 むしろ
const unsigned int MAX = ...//0かもしれない
for(i=0; i<MAX; ++i)
{MyArray[i]=...}
こんなソースをdo-whileでどうやって書いているのだい?
書き換えられる物なの?
do { if(i>=MAX) break; } while(1);
320 :
318 :2009/08/16(日) 21:37:06
>>319 そうきたか。
do {
if(i>=MAX) break;
MyArray[i]=...
} while(1);
ってことね。
>>313 見た目の問題で do-while 使用するぐらいなら、複雑性を取り除く
努力をした方が建設的だと思うのだが。
多重ループの内周を関数化するとか、適度な意味や長さで関数を分
割していけば、そうそう複雑な階層を持つ事はないだろう。
また、do-while の「一度は実行される」という特性は、想定外の問
題に繋がりやすいので、登場したら危険視している。
とりあえずinline付けときゃOKなの?
とりあえず、インラン娘は2,3人でいい。
>>323 C++に詳しい人に対してです。
なんかinlineはコンパイルされるときに短くしてくれる時があるんらしいんですよ。(本を読む限り)
だからとりあえず付けるのかなぁと。 それとも付けたらマズイ事が起きるときあるの?
326 :
322 :2009/08/16(日) 23:37:15
>>325 > なんかinlineはコンパイルされるときに短くしてくれる
> 時があるんらしいんですよ。(本を読む限り)
その本は窓から投げ捨てるために生まれてきた物です。
> とりあえずinline付けときゃOKなの?
> だからとりあえず付けるのかなぁと。
もしそうだったら言語仕様として無指定の時は全部
inlineになっているはずでしょ?
> それとも付けたらマズイ事が起きるときあるの?
バイナリが肥大化する可能性がある。
後はまあリンク時にどうするとか関数のアドレスがとれなくなるから
どうするとか説明がめんどくさいので、
詳細は次の人どうぞ!↓↓↓
EXEが異常に巨大化するという、弊害が発生します
>>226 関数アドレスを取ったら、inlineが無視されるんじゃないかなと。
適当なことをいってみる。
329 :
325 :2009/08/16(日) 23:42:59
>>328 カンスウあどれす? スマンまだ勉強始めたばっかでわからんw 出直します。
330 :
326 :2009/08/16(日) 23:44:59
>>328 無視されるかもね。
あるいは関数アドレスが必要じゃないところは
一部だけinline展開されるかもしれない。
その辺はコンパイラの自由だからなぁ。
初心者は速さやコード量を気にすると決まって糞コードを書き始める。 だからそんな下らない事気にするのは止めとけ。
332 :
326 :2009/08/16(日) 23:54:19
つーかもうコンパイラの最適化に任せるのが良いかと。 inlineは俺は関数定義をヘッダーに書きたいときに リンカエラーがでなくて便利だから使わせてもらっているぐらいかな。
Premature optimization is the root of all evil.
inlineキーワードはコンパイラへの単なるヒントであって、 実際に行われるかどうかはわからない。
>>321 if(i == x)
{
do{
/*.........*/
}while(i == x);
}
とかなら・・・いや、複雑だな。
336 :
デフォルトの名無しさん :2009/08/17(月) 09:35:04
C++で継承を禁止するクラスの制作をしたいのですが、何かいいアルゴリズムはないでしょうか?
最適化に神経質なコンパイラならinline指定は無視した上でインライン展開し捲くり、 関数ポインタが必要だったり外部リンクが必要な場合に備えて関数の実体も作る。 関数内の静的変数については、どっちみち関数の実体に関係なく作られる。
INTは1,2,3のどれかの値を取ることが確実に分かっているとき、 switch(INT) { case 1 : return 1; case 2 : return 2; case 3 : return 3; } これと switch(INT) { case 1 : return 1; case 2 : return 2; default : return 3; } これと switch(INT) { case 1 : return 1; case 2 : return 2; } return 3; これはどれが最速でしょうか?
342 :
339 :2009/08/17(月) 11:25:10
>>340 そうですよね。
では
switch(INT)
{
case 1 :
return val_1;
case 2 :
return val_2;
case 3 :
return val_3;
}
これと
switch(INT)
{
case 1 :
return val_1;
case 2 :
return val_2;
default :
return val_3;
}
これと
switch(INT)
{
case 1 :
return val_1;
case 2 :
return val_2;
}
return val_3;
これはどれが最速でしょうか?
さぁ実測しようか…
コンパイラの最適化能力の度合いにもよりけりだろうが… 全て同じ asm コードになる可能性もあるな
345 :
342 :2009/08/17(月) 11:38:48
コンパイラはgccです。 gccの最適化はこういったものは期待していいですかね?
こういう極めて小規模な部分だと、ターゲット環境のアーキテクチャによってもかわるだろうから… 実測するのが一番だと思うよ? 最速云々って そのコード部が一番遅い(or 速度に支配的) って断定できてるの? 目先にとらわれすぎているような気がしないでもない
>>346 目先にとらわれています。
ですがこの様な状況が過去にも将来にも多発するので、
どちらが速いかとかがあれば是非教えていただけますでしょうか
348 :
337 :2009/08/17(月) 12:23:02
(最適化なしでの話)
switchも結局asmでは==の比較とアドレスジャンプで出力されるはず
よって命令数で言えば下<上=中
が、いくら時間のかかる比較命令でも、1命令差を評価するのは難しい/あまり意味がないかと
OSの割り込みにもシビアに影響受けるし
>>341 virtualでhogeを継承して、コンストラクタを定義せずそれを継承するから
hogeコンストラクタにアクセスできないとか、そんな仕組みなのかな?調査してみる。thx
>>347 INTが例えば引き数なのか演算結果なのかでも事情が異なるので、そのswitchだけでは判断できない。
val_1, val_2, val_3が定数か変数かでも結果は変わるだろうし、定数の場合は法則性の有無でも変わるだろう。
あー、コンパイラにINTが1〜3以外の値を取らないと言うヒントを与えることができていないので、
一番上とそれ以外とでは質的な違いが生じている。
案外、
if (INT == 1) return val_1;
if (INT == 2) return val_2;
return val_3;
の方が速いかもしれない。
>>348 最適化なしでの議論は全く無意味だと思うし、中と下は結局のところ同じロジックだと思うぞ。
少なくとも、上と中で同じ出力になるとは思えない。
# その理由は>349の4行目
値が連続したswitchは最適化が効くとジャンプテーブルに 変換されて、cmpが消えるという話は聞いたことがある。 しかしVC2008expressで自分でやってみてデバッガでASM表示しても 消えてなかったんだよなぁ。 実測しても自前で関数アドレステーブル使った方が速かった。
352 :
337 :2009/08/17(月) 13:16:13
>349 ああ本当だ、上のほうが判定命令+1だった。スマソ
>>351 仮にジャンプテーブルに変換したとすると、より遅くなるから敢えて避けているんだろ。
関数テーブルを使う方が速いと言う話も、今回のケースには当て嵌まらない。
>>354 生波形の形に変換して、好きなように加工すればいいと思います。
例えばWindows特有の所謂wavファイルをそのまま扱っているのなら、
それのフォーマットについて知る必要がありますが。
>>355 テスト用にWindowsXPの起動音を読み込んで、再生出来ることを確認した後
データチャンク以降に格納されたデータをBYTE型の配列に格納するまでは進めたのですが
その配列に格納したデータを直接操作(演算?)する、といった感じで良いのでしょうか?
いまいち説明が上手くできないです、申し訳ないorz
ヘッダのbit数と符号の有無を確認して、bit長ごとに オーバーフローしないように足してけば良いと思うよ。
360 :
デフォルトの名無しさん :2009/08/17(月) 14:15:17
>>354 アルファブレンドってなってるからやろうとしてることは画像のピクセルの色合成と理屈は一緒だよね
画像の方はVRAM上の2次元配列のピクセルなんかとテクスチャのピクセルの色合成
音の方は時間軸方向の1次元配列(ステレオならx2)の波形の合成だろうし
>>358-360 ありがとうございます。
少しずつ確認しながら実装してみようと思います。
参照について質問です。 「参照は初期設定した後は変えられない」と禿本やEffective C++ には記載されているのですが、以下のコードはコンパイルできてしまいます。 なぜでしょうか?VC++2008、Comeauでも成功します。 int main() { int i = 1; int& r = i; int j = 2; int& s = j; r = s; //なぜerrorにならない? 参照 r は i を参照し続けるのではないのか? }
代入と初期化の違い。 int& r = i; は r を i で初期化しますが、 r = s; では、rの参照していうオブジェクト、すなわち i に s の値(= 2) を代入します。
>>363 レスどうも。
そこは理解できました。
ただEffetive C++の第5項では以下のようなコードは
代入演算子をコンパイラは自動生成しないとあり、実際
コンパイルできません。
>>362 がOKなら、こちらも
w1 = w2 はコンパイルできてもよさそうなんですが、
そうはなりません。なぜでしょうか?
int gi = 123;
class Widget {
int& r;
public:
Widget():r(gi){}
};
int main()
{
Widget w1, w2;
w1 = w2; //エラー
int x;
cin >> x;
}
>Effetive C++の第5項では以下のようなコードは >代入演算子をコンパイラは自動生成しない 自分で答え書いてるじゃない。w 自力でoperator = を記述すればちゃんと機能するよ。
>>364 現状の言語仕様については >365 の言うとおりなんだが、
確かに w1.r = w2.r としてコンパイルできてもよさそうな気もしてきた。
なんか危険なケースがあるのかな?
危険とかじゃなく、参照はポインタのように再割り当てができないから。 int&をint*に置き換えた場合を考えてみるといい。
再割り当て、じゃなくて 「中身を代入する仕様になぜしなかったのか?」という話だよ。 int &r = x; r = a; では、再割り当てなんかされずに「aの持つ値が代入される」のだから。 お前の大好きなポインタの形で書き直すならば *p = a; という形での代入が、 通常の式においては行われるのに 構造体の代入においては何故行われないないのか、ということだ。
369 :
デフォルトの名無しさん :2009/08/18(火) 03:12:19
アセンブラのコード想像したら参照は初期化したら変更できないというかできる必要は無いと思ったw
何それ。 int a, b; int& x = a; int& y = b; x = y; これが値の代入になるのは当然だよな。 でも、構造体のメンバ同士の代入になると違うって? C++において、「構造体の代入」とは「全メンバを個々に代入すること」と定められている。 (代入演算子をオーバーロードしない限りは、ね) ならば、参照メンバであっても代入は代入とされてもおかしくは無かったんじゃないかね。 まあ個人的には、「デフォルトコンストラクタが作られない」のに「代入演算子はデフォルトで定義される」という仕様になるのが 受け入れにくかったんじゃないか、とは思ってるんだけどね。
>>371 おいおい。値の代入してどうするんだよw
x=yは、つまりa=bのことだろ。
相変わらずxはaを指し、yはbを指している。
だが、本当に参照の代入を作ってしまった場合、意味的には
xはbを指すように変更されないといかん。
参照の意味わかってんのか?
>>373 >>371 さんが言ってる代入とは、a = b のことだと思いますよ。
要は、何故そのセマンティクスがクラス内の参照データメンバにも
適用されないのか?ということです。
だから、勝手に値の代入なんかされたら「意味」変わってしまうだろ。 とある変数Xを参照しているメンバーint&を持っているクラス同士をコピーしたら、なぜかXの値が書き変わるとか拷問かよw
今 見てみたら訳が分からない事になっているんだが 結局みんな何が言いたいのだい?
>>375 参照先が変わらなくても、ユーザー定義型も
>>362 のように参照先の値
が代入されてもいいんではないかと思ったわけです。
>>377 class A
{
public:
int &a_;
A(int &a):a_(a){}
};
void main()
{
int x = 0;
int y = 1;
A m(x);
A n(y);
m = n;
//↑何故かm=nで、xの中身が1に書き変わる
}
こんなのが通ったら、どんだけバグの温床になると思ってんだ。
>>378 ↓が OK なのにメンバだけ禁止するのはなんで?って話だよ。
int x = 0;
int y = 1;
int& m = x;
int& n = y;
m = n;
//↑何故かm=nで、xの中身が1に書き変わる
まぁ、クラス内に参照型が潜んでるのに気づきにくいだろうとは思う。
そういう代入を認めるように operator = () を定義するのは簡単だけど、
逆にそういう代入をデフォルトで認めた場合に禁止するための直接的な
記法( C++0x の = delete )も無かったわけだし。
>>378 なるほど、そうですね。
いっそ
>>362 もエラーにしてくれたら一貫性
があって悩むことはなかったのですが。
>>379 お前なぁ・・・
ほんとに「参照」「初期化」「代入」の意味が分かってねーんじゃねーのか?
どのプログラムの何が「何故か」なんだよ
もろにそうなるようにプログラムを自分で書いてるじゃねーか
だが、クラスの代入まわりは「自分で書かない」からバグの温床になるような仕様を避けてるんだよ!
みなさん本当にありがとうございました。 C++の奥深さを感じました。
>>362 については最適化をまったくしないベタなアセンブラで考えるとよろし
>>383 C++つーかアセンブラ的に考えると別に不思議でもなんでもない話
>>381 結論に異論はないんだけど、この内容に「参照」「初期化」「代入」の意味は
関係ないでしょ。現行の規格を前提としない話なんで、どちらの動作でも
「そういう意味」として定義可能だし。
>クラスの代入まわりは「自分で書かない」からバグの温床 >になるような仕様を避けてるんだよ! デフォルトでこんな代入演算子を書かれたら困りますね。 P30を読み返したところ納得できました。
>>384 >>385 アセンブラは未勉強なので、これから調べてみます。
>>386 自分も結論に異論はないです。危険を避けるための
仕様だとして納得しました。
アセンブラ関係ないよ。 C++ でクラスの代入を memcpy() みたいに考えるほうが危険。
390 :
デフォルトの名無しさん :2009/08/18(火) 12:30:42
>>381 どうみても、わかってなくて頭悪いのはおまえだろ
一人だけ話を理解できてないのだから
初期化の話なんかしてなくて、代入時の動作についてだけ話しているのに 一人だけ初期化と代入の区別がどうのと言っているしね。
結論が間違って無くても、無駄に偉そうな口調で書くと損をするという良い例。
>//↑何故かm=nで、xの中身が1に書き変わる >こんなのが通ったら、どんだけバグの温床になると思ってんだ。 参照ってのを理解しているとは到底思えない。
>>392 低学歴は、いったん言い方に対してファビョると、
肝心の言ってること自体をまったく見なくなるからね。
そういうのが大勢いる場所では、損をするというか、中身のある会話が終わる。
質問者が、初期化と代入の違いがわかってなかったのが原因としか思えないんだが。 int &a = b; a = b; 上2つが全然違うものだと知らなかったからもめたんだろ
C++の演算子の使い回しが元凶
参照自体が元凶 実質、実装方式がポインタなのだから、ポインタだけで良かったのに
>>396 Effective C++を読んでいて、ユーザー定義型と基本型での動作が異なる
ということが疑問だったのです。
質問の意図が通じてない方もいるようなので、この辺で止めにしましょう。 みなさんありがとうございました。
参照をメンバに持ってるんだったら、参照先をコピーするべきだよね。 参照に限っては参照先の内容をコピーするような実装を要求するのはおかしくね? そうしたければ自分で書きなよ、というのは素直な流れじゃないかなあ
とりあえず、最初の
>>362 の時点で、参照が何なのかさっぱり微塵もわかってないのに、
なんでそんなに上から目線なんだ?
そして、
>>363 のレスで「理解できた」と言っているのに、なぜ今度は「初期化」だの「代入」だのは関係ないとか騒いでるんだ?
参照をポインタに置き換えて考えれば、わかりそうなもんだけどなー >378の説明が全てだろ 参照先がコピーされるのならともかく、参照先の内容がコピーされるとか勘弁してくれ
ところで、クラスのメンバーにクラス外のオブジェクトの参照を持たせる場合ってどんな場合? オブジェクトの寿命管理がすごく面倒そうだけど。
いや、だから元質問者も含めて、ここにいる全員が参照の意味わかってるって。
元の質問はつまり、下の例でなんでFooは代入演算子が自動生成されるのにBarは違うんだ?ってことだろ
struct Foo {
int n;
Foo(int i) : n(i) {}
};
struct Bar {
int& n;
Bar(int& i) : n(i) {}
};
int main()
{
int i = 123, j = 456;
Foo foo1(i), foo2(j);
Bar bar1(i), bar2(j);
foo1 = foo2; /* operator=が自動生成されるので代入できる */
bar1 = bar2; /* operator=が自動生成されないので代入できない */
}
それで
>>387 でなっとくしてんだろが。
なぜプログラム系の板にはIDがないんだw だれが質問者でだれが回答者なのかわからねえよw
>>406 それに対する答えが、何度も書かれてるじゃないか
そして
foo1.n = foo1.n;
bar1.n = bar2.n;
この二つの意味する内容がまったく違うのに、何度も同一視しようとするから「参照を理解してないだろお前」と言われるんだ
「参照先がコピーされればいいのに」ならまだ分かるが、なんで「参照先の内容がコピーされる」なんて馬鹿な考え持つんだ。
インスタンスの「代入」の意味がわかってないと疑われる理由がそれだ。
うちのEffectiveC++の5項にはWigetクラスなんて出てこないし P30みても何の解決にもならないんだけどどうしましょう
410 :
406 :2009/08/18(火) 16:32:06
>>408 俺は元質問者じゃねえよw
たしかにそういう馬鹿もたくさん見てきたがこいつはどうみても違うだろ
>>409 俺もおんなじこと考えてたw
45項の間違いじゃねーかなw
このスレに質問するまでもなく、45項に懇切丁寧に「なぜ代入演算子を自動生成しないのか」が説明されている件。 物わかりが異常に悪いのも含めて、釣りだったのかと。
>>411 第2版と第3版で書いてある場所が違うのだ。
第3版はテンプレートの話がかなり増えたので
全体の構成がかなり変わっている。
で、2版の45項は3版の5項に移行した。
俺はEffective C++の第三版を買って持ってるよ。 でもまあ要らないか。
416 :
415 :2009/08/18(火) 17:14:22
×でもまあ要らないか。 ○でもまあもう解決したようなので開く必要はないか。 Scott Meyers大先生に恐れ多いことを言ってしまった。
FugaがHogeをメンバ変数に持ち HogeがFugaへの参照を持っています Hogeの持つ参照にメンバの所有者の参照を渡して初期化したいのですが コンストラクタ初期化子にthisを渡すと警句が出てきます これを安全に初期化する方法はありますか?
Hogeのコンストラクタで、Fugaのメンバにアクセスしたり、メンバ関数を呼び出したりしなければ問題ない。 これを守った上で、警告を明示的に抑制し、その旨をコメントに残しておく。 警告の抑制が気に食わない場合は、あきらめてポインタを使う。
超間抜けな質問ですが、VC++(cl.exe, link.exe) で C++ クラスを 含んだ DLL って、どうすればコマンドラインから作れますか? X:\> cl -c -EHsc hoge.cpp X:\> cl /LD /DLL -o hoge.dll hoge.obj として作ってみたのですが、dumpbin /exports hoge.dll では まったくシンボルがエクスポートされておらず、現在クラス内の メソッドに一つ一つ __declspec(dllexport) を付けて回ってようやく エクスポートされている状態です。 しかし可視性はC++なのでpublic/privateで制御できてる訳で、 せめてクラスに対して1つだけ指定すればクラス内シンボルは public/privateの指定に従って制御できないかと思うんですが、 何か方法があるでしょうか?
>>419 class __declspec(dllexport) MyClass {...
でできへん?
>>420 うぉ、でけた!
__declspec(dllexport) void hogefunc(...) { ...
と付けていた流れで
__declspec(dllexport) class MyClass { ...
とやって怒られてorzしてた所だった。豚々トンクス。
うお、誤爆スマン
424 :
デフォルトの名無しさん :2009/08/19(水) 00:19:11
アロケータを自作してみたのですがどれぐらい速くなったのかわかりません。 速度を計測してみると、 1000回実施 アロケータ : 0.453sec newとdelete : 0.484sec 1000回で31ミリ秒って速いのでしょうか? 比べるものがないのでよくわかりません。
比べるのは君の動機/目標だよ。
メンバ変数の順序を変えると処理速度が変わる、って有り得ないですよね。
積極的に再配置する言語も有るくらいだし
ソースの特定部分の逆アセンブルを見るのってどうやってる? コンパイラやIDEによっても違ってくると思うけど、それぞれに一般的な方法ってある?
>>429 わざわざ逆アセンブルしたのを見なくても、普通はコンパイラからアセンブリの段階の
リストを出力できるようになっている。
>>430 言われてコンパイルオプションを探してみたら確かにあった。
VCの一覧だとリスティングファイルとしか書かれてないから気付かなかったよ…
ともあれサンクス。
とあるクラスAのインスタンスが5個あってある処理を排他的にするため staticなCRITICAL_SECTIONをメンバに持たせているわけですが こんどクラスAとは全く関係ないクラスBも同時に排他する可能性が出てきたため これまでの方法だと不都合になってきました。 こういう場合はどうCRITICAL_SECTIONを利用するのが良いでしょうか・・・
・グローバルにする ・A、Bとは別にCSのみのクラスを作り、ABインスタンス生成時に渡す ・AかB片方にCSを持たせ、持たないほうの生成時に持つほうを引数で渡す
クラスA・Bそれぞれに static CRITICAL_SECTION* をメンバに持たせて最初の生成時に渡す ただこの方法だとAとBでCRITICAL_SECTIONが同一とは保証されないからバグのもとになるかも?
安易にやっちゃうとデッドロックしそうな気が… Aのみ利用の排他群 Bのみ利用の排他群 A,B 両方とも利用の排他群
使われる側じゃなくて使う側で排他したほうがいいんじゃね?
適当なfacadeを作って、そいつに依頼すると A,Bのインスタンスのコピーを返してくれて それをclientで操作した後にfacadeに渡すとそのデータを用いて更新してくれる 丁度RCSのclone, commit操作みたいなやつがいいと思う こういうのって何パターンって言うんだっけ…
>>313 for(i=0;i<10;i++){
{//block 1
}//end of block1
}//end of for (i)
とかしてるけど。
>>438 …なぁ、begin〜end とか if〜endif とかいう文化があ
る中で、何故 C は {} を採用したか考えたことある?
そんなの書かなくてもキーボード操作一発でブロックの終了位置に飛んだり 別画面で確認したり光らせたりするエディタマクロ書けばいい話
そんなマクロをわざわざかかなきゃいけないような エディタを使わない方がもっと良い。
いや、道具が気に要らなければ使い易いように改造するだろ…
改造はするけど大抵はできあいのマクロなりなんなりで十分じゃね? そんな自分でマクロを書かなきゃいけないような…(ry
>>440 何でって、そのwikiのページにも書いてるじゃない。
>しかし、この方法では同じコードをソース内の2ヶ所に記述しているため、修正を行う際に問題となる。
446 :
440 :2009/08/19(水) 20:50:04
>>445 ああそうなのかー。
ありがとうございました。
質問です。 class Hoge : public Base { virtual void test() { Base::test(); } }; と書くことで、親のtest()を呼び出すことが可能なのは良いのですが、 「自分の1つ親」を表すキーワードなどはないでしょうか? 時々継承元を、派生形のものに変えた際、 class Hoge : public BaseEx { virtual void test() { Base::test(); } }; と変え忘れてしまい、バグの元になってしまっているのです。
>>447 C++規格策定の段階ではderivedというキーワードが実は存在したらしい。
が、「typedef Base derivedでいーじゃん」の一言により撤廃されたらしい。
そのTypedefを忘れるから困るというのに、困ったものですねw 仕方ないのでマクロでも使うことにします #define ParentClass Base class Hoge : public ParentClass{ virtual void test() { ParentClass::test(); } } 美しくないですねー。 undefしてやらないと、他に影響を与えてしまいますし。
ヘッダーファイルに関数の実体を書くとインライン展開される ことが多いようですが、そう考えると予約語のinlineはどんな時 に書くのが有効なんでしょうか。
インラインで展開されてほしい気持ちを それを読んだ人間に伝えたいとき
>>450 その理解レベルなら、全く書く必要はありません。
>ヘッダーファイルに関数の実体を書くとインライン展開される >ことが多いようですが、 「ヘッダファイルに実体を書いた」からインライン展開されるのではなくて、 クラス定義の内側に関数の実体を書くと暗黙にinlineがついているかのようにコンパイルされる。 したがって、クラス定義の外側に書いた関数については、必要ならば明示的にinlineを書く必要がある。
コンパイラオプションのインライン展開なんちゃらを活用したいとき
>>449 その気持ちの悪いマクロって、typedefと何が違うの?
>>450 inlineを書かないとリンクエラーになるとき。
>>455 俺もそう思った。
むしろtypedefの方が良くないか?
いちいち undef するまでもなく、typedef だとスコープきかせられるよね class Base { public: virtual void test() { printf("Base"); } }; class Hoge : public Base { typedef Base derived; public: virtual void test() { printf("Hoge"); derived::test(); } }; class Huga : public Hoge { typedef Hoge derived; public: virtual void test() { printf("Huga"); derived::test(); } }; main() { Huga huga; huga.test(); }
__super っていう拡張があったな。どのコンパイラか忘れたけど。
MSのやつかな。 多重継承の時はどうなるんだろうね
>>455 気持ち悪さに加え、悪影響を増やしたものだよな
Java の super キーワードって有難いんだな
勝手に推測されても困るし妥当じゃね
>>447 >>448 コンストラクタにderivedを明記しておくと、派生元を変えてtypedefを直さなかったらエラーになるから便利だよ
class Hoge : public fuga
{
typedef fuga derived;
public:
Hoge()
:derived()
{
}
virtual void test()
{
derived::test();
}
}
>>455 ,457,458
クラス内の typedef だと、基底クラス変えたいときに2箇所いじることになるじゃないか。
467 :
デフォルトの名無しさん :2009/08/21(金) 08:52:31
Cで簡単なシェルを作っているのですが、フォアグラウンドプロセスグループの切り替えのあたりで詰まってしまいました。 main(){ while(1){ printf("my-shell $ "); if (fgets(input, sizeof(input), stdin) == NULL) { //コマンドの読み込み。 exit(0); } (コマンドの解析。長いので略) (fork実行) if ( pid == 0){ (子プロセス、コマンドのexec。) } else{ (親プロセス) sigaction(SIGTTOU, &all_act, NULL); //シグナルハンドラは何もしない。実質無視。 sigaction(SIGTTIN, &all_act, NULL); //これも。 setpgid(pid, pid); //子プロセスのpgidを変えて、 tcsetpgrp(STDOUT_FILENO, pid); //それをフォアグラウンドに。 waitpid(-1, &status, 0); } } } おおよそ上のようなコードを書いたのですが、一回目のコマンド実行はうまくいくのですが、 ループの先頭に戻って2回目にfgetsが呼ばれると、なぜか何も入力していないのにEOFを読み込み、exit(0)でシェルが終了してしまいます。なぜこのような動作をするのでしょうか? シェル自身がバックグラウンドプロセスになっているせいなのでしょうか?
#define のマクロを「そのファイル内だけで有効」にする方法はあるでしょうか? #undefを末尾に書くのも良いのですが、漏れなどが怖いので
外してたらスマン パイプ通すのに stdin を dup した場合って dup元の stdin は、それ以降無効になったような気が…
470 :
デフォルトの名無しさん :2009/08/21(金) 09:22:14
>>468 1) そのソースの先頭に書く
2) #ifdefで制御する
471 :
467 :2009/08/21(金) 09:37:01
>>469 返信ありがとうございます。でもパイプを使わない簡単なコマンドでもダメなんですよね・・・
#pragma(winmm等)は、その効果を 複数のソースファイルで得たい場合でも、 どれかひとつのソースのみに 記述すればいいのでしょうか。
>>470 ソースに書いたとしても、そのソースでヘッダをincludeしていた場合、そっちのヘッダにも適用されてしまいますよね。
ifdefで制御というのはよくわかりませんでした。どんな感じでしょうか。
また、ヘッダで使いたいと考えています
474 :
デフォルトの名無しさん :2009/08/21(金) 11:11:48
>>473 ヘッダー名はhoge.hと仮定
有効にしたいマクロを下記の感じで囲う
#ifdef MAC_ON
#define hogehoge 10000000
#endif
で有効にしたいソースで下記のように記述
#define MAC_ON
#include "hoge.h"
有効にしたくないソースだと
//#define MAC_ON これを入れない
#include "hoge.h"
>>474 すいません。こちらが利用意図を正しく伝えられていないみたいです。
改めて説明させていただきます
hoge.h---------
#define POWER 1
class Hoge
{
};
--------------
こんな感じでやる時、このヘッダファイルの中でのみPOWERマクロを有効にしたいのです。
他ヘッダや、hoge.hをincludeするCPPなどには影響を与えたくないのです。
全て末尾でundefする方法もあるのですが、数が多い時に困りそうです。
>>475 #undef 忘れを警戒するぐらいなら、そもそもマクロを使わないで済まないか
よく考えたほうがいいんじゃないかなぁ。
>>472 VC++とかの#pragma comment(lib, ...)のこと?
これに関しては、リンク時に働くものなので、
1つのソースにしか書かなくても一緒にリンクするものすべてに影響が及ぶよ。
>>475 class 内で static const int とか
479 :
472 :2009/08/21(金) 12:42:15
>>477 なるほど、分かりました。
ありがとうございます。
undef忘れを警戒するだけなら #define enable_macro ( #define POWER enable_macro 1) #undef enable_macro #undef POWER
>>447 の解決方法が俺も知りたいのだけど
継承元が変わった場合
やっぱり最低限2か所書き変えるしかないんですかね?
これでいいんじゃあないの class Base { protected: typedef Base base_type; void f() { cout << "Base" << endl; } }; class BaseEx: public Base { protected: typedef Base base_type; void f() { cout << "BaseEx" << endl; } }; class Derived: public BaseEx { public: void f() { base_type::f(); } };
>>482 BaseExの中のtypedef、さっそくタイプミスしてません?
484 :
デフォルトの名無しさん :2009/08/21(金) 17:51:30
うわ、こっちのスレで聞いた方が良かったかもしれないのかな
485 :
467 :2009/08/21(金) 22:01:54
すみません、どなたか
>>467 分かりませんでしょうか?
関数テンプレートの関数型宣言ってどう書くの? 書けないんだが。
489 :
467 :2009/08/21(金) 22:36:31
>>487 _exit()にしてみましたが状況は変わらないみたいです・・・
fgetsの前にstdinをfflushしてみたりしてもダメでした。
.dllってなんですか? クラスみたいに使い回しができるんですか?
>>490 そうです。いろんなプログラムから使い回しができます。
492 :
デフォルトの名無しさん :2009/08/22(土) 02:24:50
質問です。 文字列同士のマッチング処理を行う必要があるとします。 その際、検索に引っ掛かりやすいよう、両方の文字列を正規化したいと考えています。 また、条件として ・マッチングする文字列は両者ともShift_JIS。半角英数から記号、漢字まで様々な種類の文字が入力される。 ・ここでいう正規化とは、一部記号の消去や、全角/半角、ひらがな/カタカナ、大文字/小文字の統一などを指す。 ・言語はC++。自分の習熟度は低め。(ちょうどEffectiveC++が面白いくらい) ・環境はWindows2000以降を想定。最終的にはDLLファイルとして出力する。 とします。 Unicode(のどれか)に変換しつつ、Boostの正規表現で置換できるかなー、と 初心者ながらに考えてみたのですが、いざ実装しようとすると思ったよりもコード量が多くて驚きました。 (Perlの文字列処理能力ってすげぇんだなあと改めて実感) もし「こうやるのが定番」とか「遠回りしすぎ!」というのがありましたら、よろしくお願いします。
493 :
デフォルトの名無しさん :2009/08/22(土) 15:12:07
bool bHoge:1; これってどういう意味ですか? コロンとC++でググっても見つからなくて・・・
ビットフィールド
>>494 ありがとうございます
なんというど忘れ…
記号系は検索しにくいからなあ。
ど忘れだと語弊があるんですかね。 昔見た事あるはずなのに、完全に忘れていた自分への失望も込めて書いたつもりでしたが。 何かお気に障ったのなら申し訳ないです。
>>498 別に気にするな。
そんなの気にしてたら2chなんてやってらんない。
501 :
デフォルトの名無しさん :2009/08/22(土) 20:04:55
Windowsにおいてメインスレッドかどうか、を判定するようなAPIはないんでしょうか? あるオブジェクトAがあって、Aのオブジェクトの内部ではメインスレッドかどうかで処理をわけたいのですが、メインスレッドかどうかを判定する方法がなく困っています。 フレームワークのようなものを作っていて、WinMain到達後にGetCurrentThreadIdをしてメインスレッドのIDをキャッシュしておく、という方法は取れるのですが このオブジェクトが、グローバル変数などのWinMainより先にコンストラクトされて走ったコンストラクタのコード上でCreateThreadされ、そのスレッド中で使われてしまうと、もはや判定しようがありません。 なにか、ダイレクトにメインスレッドかどうかを判定する方法はないのでしょうか? たすけて・・・
503 :
492 :2009/08/22(土) 22:28:33
>492ですが、自己解決しました。 移植性などを考えるとあまり良い方法では無いのかもしれませんが、LCMapString で何とかなりました。
504 :
デフォルトの名無しさん :2009/08/22(土) 23:51:20
>>502 ありがとうございます。
そこにも書いてあるのですが、Thread32Firstを用いたときに、最初に取得できるスレッドがメインスレッドなのかどうかということがMSDNのドキュメントで確約されているものを見つけることができませんでした。
たぶん、平気だろう、ではできそうなものですが、安全性を考えると正直、つらいかなと思っています。
また、システム中すべてのスレッドを列挙するとなると、コスト的にも少々見過ごせないという思いもあり、だったらしょうがないですが、ユーザになんらかの制約を求めるほうがいいかなと思いました。
ということで、うまい解決方法がさっきからいくら探してもでてこないので、あきらめようかと思っています。
情報、ありがとうございました。
505 :
デフォルトの名無しさん :2009/08/23(日) 00:04:13
クラスを参照渡しするときに、mainで渡すと問題なく実行できるのですが クラスの中で渡すと下記のエラーが発生してしまいます。 "演算子 '%' は、値型または ref クラスのインスタンスにのみ適用できます" このエラーを回避するためにはどのようにすればいいでしょうか? おk: main(){ A^ a; B^ b; b->(%a); } マズー: ref class Z{ A^ a; B^ b; b->(%a); }
507 :
デフォルトの名無しさん :2009/08/23(日) 00:13:33
>>506 thank you for your kind advice :-)
>>501 自分なら、ユーザにこのスレッドをメインスレッドとするとフレームワークに登録させる仕組みにするかな。
そもそもWindowsにはメインスレッドという概念は存在しない。
GetMessageするスレッド?ウィンドウを作るスレッド?
どっちもただ1つのスレッドでやるなんて決まりはないよ。
必要とあれば、複数のスレッドで行って全然問題ないし、実際そうすることもある。
最初にmainが実行されるスレッドのことを言ってるんだろ。
More Effective C++の次はなにがお勧め? Coding Standards Effective STL Modern C++ Design あたりで迷ってるんだけど
Exceptional C++
PS3購入で知っておいた方が良いこと 旧型PS3: Linuxインストール機能内蔵でPS3をPCとして使うことができる。 また、Cellの開発ツールも無料で入手できるので自分でCellのプログラムを作ってみることができる。 ビットストリーム出力はドルビーデジタルPlus、dts-HDのみ対応。 HDD80G 薄型PS3: Linuxインストール機能は提供されない。 ブラビアリンク機能でブラビアと連動した電源のON OFFができる。 ドルビーTrueHDのビットストリーム出力対応。 HDD120G 比較して低騒音低発熱
全単写mapってどうやって実装すればいいかな
全単写mapって?
ああマップチップというかタイルパターン化されてない一枚絵のマップのことかね?
keyとvalueが全単写にの関係になってるマップのことです 簡単にいうとkeyに重複無し、valueにも重複無しなマップです
他人に通じにくい単語をあえて使うのは 無闇に英単語を織り交ぜて、俺ってかっこいー精神とかわらんな
全単射?
>>520 普通に大学で勉強していれば全単射くらい知ってるだろう
全単写はしらんが
理数系じゃないと厳しくないか
自分の世界=普通 これ常識
だからといって、自分の無知を正当化できるわけではない。 あぁ。
っていうかググレカス
全単射くらい中学生でも理解できるんだからもったいぶらずに教えてやれand分からないなら調べろ
と本人が申しております
std::map2つ使ってどうやって全単射を実現するのかわからない まさかkeyとvalueを交換したのを2つ作って2回代入するのか?
>>520 全単射という言葉くらいは常識かと。知らない方がはずかしい、とは感じないのですか?
他人に合わせて言葉を変えられないヤツの方が恥ずかしいわ。 結局、自分はその言葉しか知らない無知ですって言ってる様なもんだろ。
× 他人に合わせて × 俺様に合わせて
全単射mapの作り方くらい中学生でも分かるかと。 そんな常識的な事も分からないなんて恥ずかしいと思わないんですか? はい、解決。
ついうっかりごりごり実装してしまいそうな感じなんだけど、楽な方法があるんだろうなぁ
その前に全単射と全単写は全然違うだろ
全単写なんてものもあるのか… これは知らなかった
>>537 ないない
グーグル先生ですら全単写をしらないからw
全単写と書いちゃうってことはまともに聞いてなかったんだろ
>>530 逆写像が必要なら、それが一番楽な方法だと思うが。
map2つだとちょっと無駄なので、 mapとset使えば良いのじゃないか。 map<key,val> m; set<val> s; //値の重複チェック if( (s.insert( v )).second ) { //無ければmapに追加 m.insert( piar<key,val>(k, v) ); } 値のサイズがでかくて2重に持つのが勿体無いなら、 値は別なコンテナに入れて、set<val*>とか set<値コンテナのインデックス>とかで それら用のコンパレータ使うとか。
Boost.Bimapか、それがだめならBoost.MultiIndexでできない?
542 :
デフォルトの名無しさん :2009/08/25(火) 05:49:11
質問! コンソールアプリケーション勉強してどんなことまで出来ますか? ブロック崩しとかシューティングとか2Dのゲーム作れますか? エロい人教えて><
543 :
デフォルトの名無しさん :2009/08/25(火) 05:58:54
できると思うよ でもグラフィック使うならdirectxなんか使うべきだろうね。複雑さやグラフィック性能考えればね。 コンソールアプリの修行をしたいって言うんならそれでもいいと思うけど
C言語を知っている事が前提で書かれたC++の書籍で、おすすめってありますか? 柴田望洋って人の明解C言語シリーズを読んだ後に明解C++を読んでるんですが、 重複する内容が多くて挫折しそうです。それとも重複を覚悟で最後まで読んだ方がいいんですかね?
>>544 この手の本はただ読めばいいもんじゃないんだから、重複する分は復習になるだろう。
まぁ、読んだだけで理解した気になりたいってのなら挫折するのも判らんではないが。
柴田の本読むぐらいならEssential C++やC++ Primerの方がいいだろうな あとAccelerated C++はCの知識のあるなしに関わらず使えるだろう
547 :
名無し学生 :2009/08/25(火) 10:48:54
Visual Basic の課題で困っております。 誰かお答えください。本当に助けてください。 1.Visual Basicの関数で数値を文字に直すCStr()とStr()の違いについて 2.戻り値の違いが確認できる方法を考え、戻り値の違いについて実際に確認し、 その確認方法と違いを具体的に述べよ。 注意:実際にやったことと、確認した違いを簡潔かつ具体的に書くこと。 3.下記の計算結果などから、Visual Basicで計算できる数値の桁数について考察をまとめ、 何故そのような制限があるかについて理由を答えよ 1) 48 x 100 - 81 2) 12 ÷ 9.3 x 247 3) 0.2 - 12 ÷ 69 4) -12 ÷ 100 + 100
C/C++の質問とはちょっと違うかもしれませんが linuxのファイル操作について質問です。 例えばlinuxコマンドのCPであるファイルを別のディレクトリ にコピーしたとして、fopenでコピー最中のファイルを開け てしまいますよね?ここでコピーが終わるまでfopenが失敗 するようなロックをかける事は可能でしょうか。 ご教授お願いします。
flockじゃだめなの?
flockってlinuxコマンドでcp中の場合もかかっているのですか?
flock()はロックしたいプロセス同士が使わないとダメ。 cpはflock()なんて感知していないから無理。 そもそも、コピー中のコピー元ファイルを開いて何の問題があるのだろうか。
コピー中のコピー元ファイルを開いて w
VC++でwchar_tの内部表現はUTF-16ですが、 以下のようにUTF-16の4バイト文字を描画しようとすると文字化けしてしまいます。 TextOutW(hdc,x,y,_T("𡚴"),2); DrawTextW(hdc,_T("𡚴"), 2, &rect, 0); なにかいい解決方法はないでしょうか。 よろしくお願いします。
555 :
554 :2009/08/25(火) 19:09:13
書き忘れました。環境はWindowsVista(64bit)とVS2008アカデミックです。 すみません。
2とはこれいかに
>>554 試してみた
Vista32bitなので若干環境違うけど、TextOutW で表示はできてるっぽい
APIの問題じゃなくて、フォントが対応してないってことはないかな?
Vistaならメイリオのフォントを明に指定して描画してみたらどうなる?
558 :
554 :2009/08/25(火) 23:00:39
フォントをMS明朝に設定したらうまく行きました。ありがとうございます。 文字コードのせいだと思い込んで、フォントのことを忘れていましたorz
559 :
デフォルトの名無しさん :2009/08/26(水) 05:55:12
初心者すぎて恥ずかしいのですが… Visual C++と普通のC++って別物ですか? Visual Studioで作ったものをNetBeansにコピペしても動くものなのですか?
VCだけの拡張機能みたいなのはあるが、 それらを使わなければコピペで動く。
561 :
デフォルトの名無しさん :2009/08/26(水) 07:59:01
ありがとうございました!! ググっても入門レベルじゃわかんなかったので助かります。 VC++だとWindows上でしか動かないんじゃないかと心配してました。 (万能求めるならJavaとかかもしれませんが…^^;)
>VC++だとWindows上でしか動かない yes
VC++のVの部分はwindows依存だからねえ VC++のVに依存するコードを書かなければ、他の開発環境のツールとしても使える ハックできるゲーム機の非公式開発のツールとしても使われてるね
>>562 半端な回答乙。
>>561 基本的に、GUIはWindows依存。
問題は、それ以前にNetBeansはC++開発環境*ではない*と思うのだが。
NetBeansで開発するとすると、大抵はJavaで最近ではRubyやPython辺りってとこじゃないかと。
565 :
デフォルトの名無しさん :2009/08/26(水) 09:22:58
長い文章書くとボロが出る典型的な例
566 :
デフォルトの名無しさん :2009/08/26(水) 10:32:45
たくさんのレスありがとうございます。 最初はNetBeansでJavaやってみようと思ったのですが、 エラーがゲリベンのごとく出てくるので断念しました。 とりあえずVisual Studio C++やってる感じッス。 今の自分にはLinuxやらMacやらに対応させるなんてのは無縁だと思うんで、 しばらくVC++やっておきます。
>>564 > 基本的に、GUIはWindows依存。
ここがもう分からない
VCのGUI=MFCみたいな意味じゃないだろうか
>>567 エスパーじゃないので、何が分からないのかを書け
570 :
デフォルトの名無しさん :2009/08/26(水) 10:53:02
>>566 鬱陶しいからNetBeansでJavaやっとけ。二度とくんな。
>>567 (・з・)キニスルナ!
VC++ に含まれるコンパイラは GUI がどうとか以前に
・プロセッサは IA-32/64。
・CランタイムおよびCスタートアップは Windows 用。
・そもそも .exe 形式。
なので、作った実行形式ファイルは 非 Windows 環境では動かない。
>>572 脇道:
MSDOS で起動すると this program cannot be run in DOS mode. って出るんじゃなかったっけ?
(ま、アプリケーションがメモリにロードしきれるかどうか微妙だけど)
コンソールアプリってのもあるけど今時16bitモードを使うMS-DOSで動くアプリを 出力できるようになってるのかね?
>>574 EXEファイルの仕様でWindows実行ファイルの先頭部分はDOS実行ファイルになっている。
そして、その中身は標準だと
>>573 の言うようなプログラムというわけ。
もちろん、予めバイナリを用意しているだけなので、今のVCが16ビットコンパイラなどを持っているわけではない。
今更だけど、言語であるC++とコンパイラであるVC++とは比較できる対象ではないだろとマジレス
ある程度は考慮しないとだめでしょw intだってレジスタの拡大で昔とは違うんだし
templateの引き数の数を可変にしたいのですが、templateプログラミングで実現できますか?
はじめまして 質問させてください Visual C++ 2008 Express EditionでC言語の勉強をしているのですが、 strcmpという関数がうまく動きません。 原因を調べると、確保した配列が確保した以上のアドレスを参照しているようです。 char ary[5]で確保した配列2つを比較したいのですが、 例えば両方にappleという文字を代入してやってブレークで止めると、 1個目が"appleフフフフフフapple" 2個目が"appleフフフフフフフフフフ" みたいな感じになってます 原因知ってるからがおられましたらよろしくお願いします
>>579 ary[6]
でないと文字列終端の '\0' が入らないから
581 :
デフォルトの名無しさん :2009/08/26(水) 13:42:56
>>579 ゼロ終端になっていない。
char ary[6];
ary[5] = 0;
にしないといけない。
strcmpは文字数の長さを指定しないのでCなど特有のお作法である文字列の終端に\0が入るスペースが必要だし入ってないと\0がでてくるまでひたすらうごくよ
VC++のデバッグモードは未初期化メモリに0xCCを入れるので そのままShiftJIISとして文字列表示すると"フフフフフ..."と笑われるのです
あの嘲笑は偶然じゃなかったのか
CCはINT 3 つまりデバッグ時のブレークポイントなので 未初期化のメモリに実行が飛び込んでも止まるという安全弁
>>578 デフォルト引数を上手く使えばなんとかなるかもしれない。
根本的な解決は次期C++かな。
そこでLokiのTypelistですよ
>>587 あの0xCCはそんな意味があったのか・・・
適当に選んだ値だと思ってた
そうするとx86以外のCPUじゃ意味ないんだな
ARMとか何がいいんだろう
>>590 そんな危なっかしいソース書かなければいいだけだろw
x86じゃないCPUは1バイトコードじゃないのはガチだろうな
68000だと"NO"辺りになるのかな?w
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
>>590 バグで未初期化の領域を見てると、ゴミが入ってると
毎回挙動が違ったりしてデバグがしにくいんで、決まった値で
埋めておくって説も聞いたことがあるんで、もしそうなら、
ブレークポイントにならない適当な値でも意味はあるな。
1000 1,000とかカンマを入れてくれる関数とかって存在しますか?
>>595 intないし文字列で表された整数に,を入れて
文字列として返してくれる関数ってこと?
よく知らんが、まあ作っちゃえよ。
文字列なんですがつくります(`・ω・´)ゞ
598 :
596 :2009/08/26(水) 23:37:38
今らかC++でゲーム作りますね
ゲームでキャラクターの向きを作っています。 0、1、2、3がそれぞれ上右下左に対応しています。斜めはありません。 これを時計回りに回転させた時に、0、1、2、3、0、1、2・・とすることはできますか? bit演算をうまく使うとできそうなのですが、よくわかりません それとも深く考えずに素直にifで3の時に右を向くと0、 0の時に左を向くと3、それ以外は時計回りで1加算、逆は減算・・としたほうが良いでしょうか
x = 1; angle = ( angle + x ) % 4; 多分こんな感じ
右回りなら1を足して、4で割ったあまり 左回りなら4を足した後、1を引いて、それを4で割ったあまり
bit演算でやるなら3で&すればOK byte dir, hoge; dir = 0; hoge = dir & 3; //hoge = 0 ++dir; hoge = dir & 3;//hoge = 1 dir += 3; hoge = dir & 3;//hoge = 0 dir = 4
順回転を +1 逆回転を +3 (= 4-1) にすれば正の値しかとらないしな
>>602-605 あまりを使うのでしたか、ありがとうございます。
bit演算も勉強になりました。ありがとうございました。
ペロッ、これはrotation group!!
むずけええええええええええええええええええええええ なんだこの数字の塊わあああああああああああああああ
609 :
606 :2009/08/27(木) 18:23:59
ありがとうございます。おかげさまで移動ルーチンは完成しました。
しかし別の問題が浮上してきました。
現在MAPを二次配列で用意しています。
int map[3][4]={{2,12,0,4},
{0,5,4,13},
{0,3,11,9},
};
自分を表す位置は自分.xと自分.yで管理しています。
このようにある時、map[3]は縦、[4]は横幅になります
ですが一般的には縦はy、横はxが多いです。どちらにあわせるべきでしょうか?
とりあえずは自分が移動するときに、横に行きたいなら自分のy座標をずらし、
縦に動きたいならx座標をずらしています
>>601 だと0の時にx--、1でy++・・となります
もしくはそうせずに、map情報を取得するときに
map[自分.y][自分.x]としたほうがよいでしょうか?
開発は趣味で一人でやっているので、他人が読むことはまずないと思います
できればミスが発生しにくいほうにあわせたいと思っています。よろしくお願いします。
class map { private: int data[3][4] = { ... }; public: int DataAt(int x, int y) { return data[x][y]; }// or return data[y][x]; }; と書いておいて、外からは常に同じように見えるようにする
>>610 そんな方法があるのですね
ありがとうございます、やってみます
>>610 範囲外アクセスでabortするようにして
参照にしたほうがよくね?
613 :
609 :2009/08/27(木) 22:45:04
ダメでした、分かりませんでした・・ mapクラスを作り、map型のF1を作り、メンバ関数DataAtの戻り値をcout・・と思ったのですが上手く動いてくれません エラーは 1>d:\program files\vc\project\no\a.cpp(8) : error C2059: 構文エラー : '{' 1>d:\program files\vc\project\no\a.cpp(8) : error C2334: '{' の前に予期しないトークンがありました。関数の本体は無視されます 1>d:\program files\vc\project\no\a.cpp(15) : error C2065: 'data' : 定義されていない識別子です。 で、コードは↓です。どこが違うのか本気で分かりません、助けてください! #include <iostream> using namespace std; int main() { class map { private: int data[3][4]= { {2,12,0,4}, {0,5,4,13}, {0,3,11,9}, }; public: int DataAt(int x, int y) { return data[x][y]; }// or return data[y][x]; }; map F1; cout <<F1.DataAt(2,3); return 0; }
インデントのないソースコードは見ないことになってる
※classはC++の新機能です
つかiostreamとか使ってるならC++の知識あるんじゃないのか? とりあえずクラスについて書いてあるところもう一回読んでみろ
617 :
609 :2009/08/27(木) 23:01:26
>>617 そこで初期化をすることはできないとだけ…
素直にループで回せや #include <iostream> class map { private: enum { COLUMN = 3, ROW = 4 }; int data[COLUMN][ROW]; public: map() { int z[] = { 2,12,0,4, 0,5,4,13, 0,3,11,9 }; int* src = &z[0]; for (int i = 0; i < COLUMN; ++i) { for (int j = 0; j < ROW; ++j) { data[i][j] = *src++; } } } int DataAt(int x, int y) { return data[x][y]; } }; int main() { using namespace std; map F1; cout <<F1.DataAt(2,3); return 0; }
>>618 ありがとうございます!
やっぱり出来なかったので諦めます!
>>619 ありがとうございます!それいただきます!
スペースを&で置換して書き込むと、インデントされる。
間違えた。 だな。
知っててもそんなアホらしい事はしないよ
すごいいい方法だよ。 見た目もインデントされるし、コピペしてもふつーの使えるコードになるし。 サイズの制限がきついけど。 よそにうpして、アドレス貼り付けとか情報が消えるし。 まあ、ログなんて誰もみないからそれは考えなくていいかな。
>>627 相手が切れて見えるのは、自分の心理の投影だろう。
意味不明なことで切れる人っているな。
相手が切れて見えるのは、自分の心理の投影だろう(キリッ
>>629 なんかあるのかと思ったけど、意味不明に煽ってるだけか。。。
まあ、
>>623-624 の件に関しては今までそれ不便とかよくないとか言われたなかったし、そうだろうな。
633 :
デフォルトの名無しさん :2009/08/28(金) 00:34:58
C++のifstreamについて質問です プログラムのコンストラクタ内でファイルオープンし、メイン内でファイルから一行読み出したいのですが、うまくいきません。 .isopenで調べてみると、コンストラクタ内ではOPENできてますがメインのほうだとCLOSEしてます。 ifstreamとはそういうものなのでしょうか。強制的にOPENしっぱなしには出来ないのですが?
>>633 どこか他の関数で読もうとしてるだろ
ifstreamの参照を渡さないとcloseされるぞ
できます、というかコンストラクタもメインも関係ない どうやってifstreamインスタンスを渡してるの?
>>626 他人のコードを見るときは常に俺スタイルにコンバートしてから読みますので何でもいいです(キリッ
グローバルスコープなファイルオブジェクトがほしいなら FILE構造体へのポインタを使うCの手法を使えばいいのだ。 これなら、一度開いたら、明示的に閉じない限り、 ファイル終了までずっと、プログラムのすべての場所からアクセス可能になる。
char a[N]; って感じで配列をスタックに作るとき、おまいらは何バイトまでなら許せますか。
8
ワーク用なら 2Kぐらい
質問です。 void Test { int a = 0; } こんな関数があるとして、この関数内で動く別関数を定義したいと思います。 その際、int aにアクセスする方法はあるでしょうか? ぱっと思いつくのはインラインクラスで void Test { int a = 0; struct Func { static void hoge() { //色々処理 } } } なのですが、そとの a にアクセスすることができません。 hogeの引数に参照として渡すのも良いのですが、数が多いと厄介です。 何か良い方法はありますでしょうか? 可能ならマクロでは無い方法が良いのですが…
643 :
デフォルトの名無しさん :2009/08/28(金) 09:29:01
可変長引数をそのままバケツリレーしたいのですが、どうすれいいでしょうか? 具体的にはprintfをラップしてmy_printfを作りたいのです。 void myprintf (const char* s, ...) { printf (s, ...); } ↑こういう事がやりたいです
>>642 void Test {
struct Func {
int a;
};
}
>>644 外のaにアクセスする方法
と書いてあるが
>>638 すいません、具体的にはどう修正すればいいんでしょうか
とりあえずtypenameを消したらコードパットのほうではコンパイルできました
しかし依然VC++EE2008ではエラーのままですFuga::f : private メンバにアクセスできません。と言われます
http://codepad.org/t9Ujbfeg
649 :
638 :2009/08/28(金) 13:42:24
C言語で、C++のstaticなメンバ変数と 同等な機能を実現する方法ありませんか? 各パラメータを、静的メンバ変数でスイッチングすることを考えています
グローバル変数使うしかないよ。 というか、C++のclass-static変数は、名前空間とアクセス制御のあるグローバル変数みたいなものだし。
if( a > 0 && b == 0 ) と言う条件式を書いた場合 a > 0 は確実に b == 0 よりも先に判定されるんでしょうか? 最適化などで順序が変わったりしませんか?
>>652 && の両辺の式評価の間にはシーケンスポイントがあるので、左辺が先に判定される
ような結果になることが保証されている。
ただし最適化後のマシンコードレベルでは、結果に影響の無い範囲で実際の判定の
順序が入れ替わってたりすることはあるかもしれない。
まあ副作用がある場合(例えば関数呼び出しを含むとか)やvolatileな変数にアクセスするとかの場合は 確実に評価順の規定通りだろうけどね。
>>650 関数内で static な変数を宣言する。
この方法の場合、参照範囲が狭い点もメリットになる。
デメリットは、変数の参照に関数呼び出しが必要な点。
>>650 .cファイルをクラスとみなして隠してみるとか。
文字列とその長さを関数内で定数として表したい場合、(C++) const char * const str = "foo"; const size_t len = strlen(str); とすると、len はコンパイル時に 3 として扱われるんじゃなくて、 (最初に1回だけか、もしかしたらlenが宣言されてる関数/スコープに入るたびか分かりませんが) 実行時に長さを計算するかもしれませんよね。 別にそのくらいいいじゃんって感じかもしれませんが、文字列とその長さをうまく定数で表現する方法はありますか。
const char str[] = "foo"; const size_t len = sizeof(str) / sizeof(str[0]) - 1;
660 :
名無しさん@そうだ選挙に行こう :2009/08/30(日) 13:56:29
VC++のプリコンパイル済ヘッダについて質問があります。 COMの初期化をすべてのグローバル変数に先立って(つまりWinMainよりも先に実行されうるコードよりもさらに先立って)行うために、 ヘッダファイルにconstグローバルオブジェクトを作成し、このオブジェクトのコンストラクタで行うのはどうかと考えました。 constグローバル変数は内部リンケージなので、このヘッダをインクルードしているコンパイル単位では、 毎回このオブジェクトがヘッダのインクルード時点で作成され、そのオブジェクトのコンストラクタが走ると考えたからです。 (多重に初期化されることについては、初期化状態を調べることで対応しました) なので、コンパイル単位をまたいでいて初期化順序が不定でも、とにかくヘッダさえインクルードされれば、最初に初期化処理が走ってくれると思い、実際そのとおりに動いているのですが プリコンパイル済ヘッダを通したときになにか挙動が妙なことに気がつきました。 プリコンパイル済ヘッダに、作成した初期化用ヘッダファイルを入れれば、各cppファイルでは先頭で必ずインクルードされるので、 ファイル毎に初期化オブジェクトが生成されるだろうと思いきや1度だけしかされません。(たぶんstdafx.cppに対応している) 僕はcppの個数分、呼ばれることを期待していたのですが、そうではないようでした。 ためしに、初期化用のconstグローバルオブジェクトにダミーのメソッドを持たせて、それをcppファイルからコールするようにしてみたところ、今度は初期化コードが使っているファイル数ぶん、走っているようでした。 このことから察するに、プリコンパイル済ヘッダというのは、#includeという「プリプロセスの動作そのもの」も、通常とは別物になる、ということなのでしょうか。 またこの場合、stdafx.cppに対応するコードが複数のコンパイル単位の中で最初に初期化されることが保障されるのでしょうか? (つまり、初期化用オブジェクトが最初に呼ばれることを保障したい)
とりあえず、コードを貼ろう
俺は気にしないことにした けど660のせいで気になり始めた
663 :
660 :2009/08/30(日) 17:39:51
>>661 もっとも単純には
class Foo
{
public:
Foo(){ ::MessageBox(NULL, L"test", NULL, MB_OK); }
};
const Foo foo;
というコードを、通常のヘッダに書いたときは、それをインクルードするcppのファイル数分のtestというメッセージボックスが表示される
たとえば2つのcppがこのヘッダをインクルードしていたら2回メッセージボックスが表示される
この動作は、C++のデフォルトではconstグローバル変数は内部リンケージなので、コンパイル単位毎に生成されるという納得のいく動作
しかし、上記のコードをプリコンパイル済みヘッダ、ようはstdafx.hに書いたときは1度しか呼び出されない
この違いはいったいなに?
ということです。
プリコンパイルは一度しかされないから?
665 :
660 :2009/08/30(日) 18:05:00
>>664 僕が何かとんでもない勘違いをしているのでなければ、プリコンパイルというのは
毎回ヘッダを読み込んで解析したりしてるとはんぱねえ時間がかかってしまうから
プリコンパイル済ヘッダを利用してコンパイル時間を短くするもん、だと思っていました
そう仮定すると、pchには解析後の結果が入っていて、stdafx.hのinclude時に使う。
だから、コンパイルにかける時間が少なくなってコーヒー飲む時間が減る。
動作としては普通のヘッダだけど、先に解析しておいて保存しておいただけだよ
と、そういうものを期待していました(今までは)
しかし、今回のような内部リンケージのオブジェクトになるはずのものが、まるでなかったかのようになってしまうのはなぜなのか
かといって外部リンケージになっているわけでもない。1度でもそのオブジェクトを(コンパイル単位で)利用するようなコードが入っていると、そのオブジェクトはコンパイル単位で初期化される
意図的に、触られないオブジェクトは排除されている、つまり単なるヘッダのincludeとは明らかに挙動が違う
しかし、今回のような件、COMの初期化にコンストラクタを利用したいような場合においては、直接は触ってないけど実行してくれなくては困る。
普通にincludeするとOKだけどプリコンパイル済ヘッダとしてincludeするとだめだよ、なんて酷い……
普通に考えると意図しない挙動だと思うのですが、これって、そういうもの?って納得するしかないんでしょうか。
(あとはstdafx.cppに対応するコードの初期化タイミングが必ず最初であるのか、そうでないのか、つまり普通のcppの規則と同じコンパイル単位をまたいだ時は不定、なのか、というのが気になります)
667 :
デフォルトの名無しさん :2009/08/30(日) 22:44:21
C#ののりでスレッドをやろうとしたら、標準ライブラリになくてとても面倒だと分かった これはアマチュアレベルを超えてるな
C#のマルチスッドレとVisual C++を使った真のマルチサレッドは 実行速度にして3倍以上の差が出ると占い師も言ってるからね。
>>667 _begintheadExがある。スレッドプールの実装も簡単にできる。
既存のライブラリを使いたければboostにスレッドプールがある。
WaitForMultipleObject()で終了待機な Win32システムプログラミングの本を買えばいくらでも マルチスレッドの例が載ってる 割と簡単だ
戻り値がメンバ関数ポインタとなるDLL関数(stdcall)を作成することは不可能なのでしょうか? メンバ関数ポインタのサイズはコンパイラ依存だとロベールに書いてあったのでもしかしたらと思い・・・ もし不可能なら、sizeofでサイズが取れるのだからそのサイズ分メモリを確保して そこにメンバ関数ポインタをコピー、確保したメモリのポインタを返すというようにしようかと思いますが 他になにか手法があればご教授くださいませ
__stdcall を使えば同じサイズになるんじゃないのかい?
>>671 作れるけど、メンバ関数ポインタはコンパイラ依存だから同じコンパイラでないと呼び出せないと思う。
コンパイラに依存しなくするためにはstdcall関数ポインタを使うしかないだろう。
たぶん、だけど 非仮想のメンバ関数へのポインタは、普通の関数と同じサイズと思われる(thisを引数にもつだけ) 仮想関数だと、vtbl内のインデックスになると思う。オフセットなのか番号なのかはわからないが。 メンバ変数だとほぼ確実にオフセットだしね。
675 :
671 :2009/08/31(月) 00:01:36
ちょっと言葉足らずだったので補足
1)DLL関数Aを呼び出して実行側はメンバ関数ポインタを取得
2)メンバ関数ポインタを引数にもつDLL関数Bを↑で取得した値で呼び出す
という流れです。
>>671 だと実行側でメンバ関数ポインタを呼び出すととれてしまいますね。すみません
>>672 >__stdcall を使えば同じサイズになるんじゃないのかい?
同じサイズとはメンバ関数ポインタのサイズでしょうか?
>>673 上述のようにとられてしまったみたいですね。すみません。
メンバ関数ポインタを用いて関数呼び出しをするのはDLL側なので、その部分の問題は(たぶん)大丈夫です。
最終的に何が聞きたいのかというと
1)メンバ関数ポインタはサイズが8とか12とかになるので、それを戻り値にできるの?
2)メンバ関数ポインタの値をコピー(2回)した後でその値から関数呼び出しって問題ないの?
ってことです。( 2)は大丈夫だと思ってますが。)
676 :
デフォルトの名無しさん :2009/08/31(月) 00:08:36
>>674 仮装関数(virtual修飾)ではありませんが、下のような構成になっています。
class Base{
class OperatorItem{ 〜 } operator_obj; //←インスタンス生成
}
class Maker: public Base{
OperatorItemクラスのメンバ関数ポインタを戻り値にもつ関数A
OperatorItemクラスのメンバ関数ポインタを引数にもつ関数B
} // 関数A、Bはstdcall関数でラッパーしてあり、実行側はそれを呼び出す
>>676 やるとすれば operator [] を定義したりするんだろうけど、
単一オブジェクトと配列がごっちゃになってるのは C のポインタの特徴であって
自然なものではないのだから、そこは明確に分けておくのが正解。
>>675 > 1)メンバ関数ポインタはサイズが8とか12とかになるので、それを戻り値にできるの?
> 2)メンバ関数ポインタの値をコピー(2回)した後でその値から関数呼び出しって問題ないの?
なんでサイズによって戻り値にできたりできなかったりすると思うのかわからん。
2つ目の疑問も同様。
DLL関数とか書いてあるから呼び出し時のことも考えているんじゃないの
681 :
デフォルトの名無しさん :2009/08/31(月) 13:22:30
>>678 聞きたいのはむしろdelete[]の方です。
実装方法がわからん。boostを使った方法ならググって見つかったんですが。
戻り値にできないってのがどういう状態のこと言ってんのかな?
>>681 「delete[]の方」と言われても何のことかわからん。何か聞きたいならちゃんと書け。
そもそも、配列と単一オブジェクトをごっちゃにできるようなスマートポインタなんて
実装して、だれが喜んでそんなもん使うの?
DLL そのものが クラスを提供しないんなら DLL内で そのハンドル値 と (メンバ?)関数のポインタ との map を作っておき DLL呼び出し側に戻すのは ユニークなハンドル値 DLL呼び出し利用側は そのハンドルを渡して処理 → map から関数のポインタを手繰って実体化させる こんな管理はどうだ?
>>665 ひどいもなにも、stdafx.hの実体化はstdafx.cppで行われるのだから、実体は1つしか作られないのが普通では?
普通のヘッダにして、各CPPに読ませた分実体ができるという挙動は、
各CPPの無名ネームスペース毎に実体化しているという挙動だよね。
>>685 >>663 のコードをstdafx.hに書いて、
オプションのプリコンパイルヘッダーファイルを使用する/Yu と
使用しない、でそれぞれビルドして実行してみ。
>>665 ちゃんと実験したか?
そのfooが実際に(stdafx.h以外の)cppでも使われていれば、ちゃんとコンストラクタが呼ばれる。
利用されてないから、実体化されてないだけ。
一応こっちでも実験したが、ちゃんと各cppでfooを利用したら、個別に生成されてたぞ
例:
Foo *p = &foo; を各cppの関数内に書く。
コンストラクタはインスタンスの初期化処理なのだから、インスタンスが不要ならそりゃ最適化で消されても不思議じゃないわ
グローバル空間の初期化の順番なんて、コンパイラの都合でいかようにしてもよいと定義されているのに 「書き方がちがったら、順番が違う」なんて文句つけるなよw 書き方がちがった結果、コンパイラが最適化を働かせて、順序が変わることだってあるんだから 実際利用前には翻訳単位毎に実体化するんだろ? ならそれはC++の正しい挙動だ グローバル空間のインスタンスの初期化が、WinMainより前に全て済ませてあるなんて規則は無い
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
>>687 君がよくわかってないということはわかった。
まあめんどくさいから
>>665 にまかすわ、ほっといてもいいしw
ソースファイル内でインスタンスを参照しないからといって、 コンストラクタ内で標準出力命令したのに、勝手にそれが削除されるのは間違った最適化だろ。
インスタンスの初期化処理であるコンストラクタで、それ以外の仕事をすること自体がどうかとw
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
で、こういう最初に初期化したいオブジェクトってどこに書くのが適切なの? ざっと調べた感じだと、全てのグローバル変数を1箇所に書いて制御しろって のが見つかったんだが、それはちょっと辛い気が・・・
グローバル変数を初期化する、関数でもクラスでも、好きなの作れ
シングルトンにしろよ
シングルトンじゃだめなん? インスタンスを初要求された時とそれ以外で区別つくしね… 『エラー処理を伴うとややこしい』のは、グローバルオブジェクトでやっても変らんしね
ある程度複雑な処理だと ckass AAA { AAA() { } ~AAA() { } 以外に int init(); void final(); } の初期化と終了関数を書くのは普通
>グローバル空間のインスタンスの初期化が、WinMainより前に全て済ませてあるなんて規則は無い グローバル空間のインスタンスの初期化が、mainより前に全て済ませてあるという規則はある。
700 :
デフォルトの名無しさん :2009/08/31(月) 19:17:06
すみません質問です。 int a = (数値0〜99); int b = (数値0〜99999); int c = (数値0〜99); int d = (数値100〜199); printf("int d=%d; char *str=\"%d%d%d\";", d, a*d, b*d, c*d); と言うプログラムがあって、dとstrを別のプログラムで取得しました。 このdとstrからa、b、cを求めるにはどう言うロジックを書けばいいでしょうか? a*d、b*d、c*dの3数値の間にスプリット文字があれば楽なんですが……
701 :
408 :2009/08/31(月) 19:39:41
Cでvoidポインターの指す先の構造体の型名が知りたいのですが何かいい方法はないでしょうか?
ないです
>>701 RTTIでぐぐってみると良いかもしれない。
と思ったらCだったか
RTTIだってPODには役に立たないんだぞ
自前でRTTIすればいいんだよね 専用malloc作るか 判別用メンバ入れるか
707 :
408 :2009/08/31(月) 20:15:41
>>702-706 やっぱり無理ですか…
根性で落ちなくなるまで全部キャストして使ってみます。
>>694 グローバル変数の初期化で悩むよりも、使わない方法で悩むほうが建設的
>>698 それはお勧めできない。俺も昔はそう思っていた。
initを忘れないようするための安全策とか、initが呼ばれなかったときの処理とか
余計な仕事が増えまくった割りに効果がなかったりする。
お前の頭がついていかないだけだな
>>710 フェイルセーフとかフールプルーフって知ってるか?
まさかそんな程度で、人にラベルでもつけてるのか?
713 :
デフォルトの名無しさん :2009/08/31(月) 21:24:16
flockfile関数とfunlock関数を使おうと思っているのですが、 コンパイル時に識別子が見つからないというエラーが出ます。 これらの関数はstdio.hにあると書いてあり、stdio.hはインクルードしているのですが、 どうすれば使えるようになるのでしょうか? 環境はWindows、VC++です。
>>713 >これらの関数はstdio.hにあると書いてあり
どこに書いてあった?
VCじゃない別のコンパイラのマニュアルの見ていないか
>>714 manページです。manページはWindowsでは必ず使えるとは限らないようですね。。
MSDNでflockfileで検索してみても0件だったので、もしかしてWindowsでは使えないという事でしょうか?
何のmanページだよ
調べてみたらlinuxのmanpageでした。 windowsでは使えなさそうですね。。。
719 :
671 :2009/09/01(火) 00:45:04
返事が遅くなりました。
>>679 コンパイラによってサイズが変わるかもしれない値を戻り値にしてしまうと
他のコンパイラや言語から呼び出し時に困らないかと思いまして
>>680 そのとおりです。
>>682 コンパイラに依存しないDLL関数の戻り値として
サイズがコンパイラ依存のメンバ関数ポインタを使えるのだろうかという疑問です。
>>684 とりあえず、現状ではそんな感じで考えています。
>>671 のメモリ確保したポインタ値をハンドル値として使う場合は確保したメモリをコレクション型などに記録して
引数で受け取った時にコレクションに入っているかどうかを確認してから使用したほうがいいですよね?
全レスうざい
とかいって省くと俺スルーすんなよって怒るんでしょ?
DLLをロードするシステムってその辺の面倒見てくれないの?
DirectXのDLLはコンパイラに関わらず呼び出せたような記憶があるけど、 COM使ったら同じようにできないのかな。
shared_ptrのコピーコストってどのぐらいのサイズのクラスから有利になるんだろう
>>687 > コンストラクタはインスタンスの初期化処理なのだから、インスタンスが不要ならそりゃ最適化で消されても不思議じゃないわ
俺もこう思ったんだけど、調べてみるとどうも
>>663 のケースでは
プリコンパイル済みヘッダ無しほうの動作が標準規格で要求されているみたい。
3.7.1 [basic.stc.static] p2 より
> If an object of static storage duration has initialization or a destructor with side effects,
> it shall not be eliminated even if it appears to be unused, ...
それでもプリコンパイル済みヘッダ自体がコンパイラの拡張なんだから、
ここらへんの動作も独自仕様になってるのかと思って MSDN をちょっとあさって
みたんだけど、特に動作の変更について書いてあるところは見当たらなかった。
ってことでやっぱりバグで以下
>>666
726 :
660 :2009/09/01(火) 12:38:38
プリコンパイル済ヘッダのことを言ったものです。
みなさん、いろいろ調べていただけたようで、本当にありがとうございます
あれからいろいろ調べたり会社の人とも話し合ったりしてみたのですが、プリコンパイル済ヘッダの件については、結局解決できませんでした
結局
>>725 >>666 さんが真実なのかなとあきらめております。
しかし、今回のようなケース、アプリケーション単位で一度だけ初期化されればいいよ、というような場合においては
#pragma init_segを使うとコンパイル単位の初期化順序を制御できるっぽいものがあることを知りました
今回のパターンだと、これ使えばいけるんじゃね?と思います
プリコンパイル済ヘッダについては、よい解決方法は探せませんでしたが、よりスマートな方法が(VC++限定ですが)あったので
こちらを使ってみようと思います。
727 :
660 :2009/09/01(火) 12:45:50
続き
>>696 >>697 シングルトンにしろ、というのはCOMの初期化をするようなシングルトンをつくってそれを経由して各オブジェクトを生成するなり(シングルトンのファクトリ)、
各オブジェクト内でシングルトンのCOM初期化関数を呼べということでしょうか?
シングルトン限らず、COMみたいなもんを使われる寸前になったら初期化、みたいなことはひとつの解決法だと思うのですが
CoUninitializeのような終了処理について問題がある気がします。
普通、この場合だったらシングルトンオブジェクトのコンストラクタで初期化(CoInitialize)、デストラクタで開放(CoUninitialize)、またはatexitに登録しておく、などのことを
をするかと思うのですが、これだとboost::shared_ptrのようなものを使っていたときに問題がおこるんじゃないでしょうか?
boost::shared_ptr<SomeObject> obj;
WinMain()
{
obj.reset(new SomeObject());
....
}
SomeObjectのコンストラクタ中で初めて初期化用シングルトンが実体化されたとすると、その時点で初期化が走るのでSomeObjectの中でCOMを使う分には問題ありません。
しかし、objそのものがデストラクトされるのは、アプリケーションの最後です。
シングルトンのオブジェクトもアプリケーションの最後にデストラクトされますが、これだとobjというboost::shared_ptrのほうが先にコンストラクトされているので
シングルトンのデストラクトより後に、デストラクトされることになります。
つまり、SomeObjectのデストラクタは、CoUninitializeが呼び出された後に走ってしまうことになります。
SomeObjectのデストラクタでCOMのオブジェクトのReleaseを呼ぶなりCComPtrのオブジェクトを持っているなりしていた場合は、すでにCoUninitializeが呼び出されてるからエラー!
となってしまいます。
解決するためには、シングルトンがデストラクト時にコールバックするような仕組みをつくっておいて、シングルトン死亡を各オブジェクトが受け取ってそのタイミングで後処理をする
みたいな構造が考えられますが、ここまでいくと、なんか別にもっといい解決方法、そうだなすべてに先立って初期化されるオブジェクトがあったらいいんじゃない?
という方向に考えてしまいます。
>>727 ぱっと思いついたのを つらるらと書く。 (定石から外れているかもしれん)
<大前提> グローバルオブジェクトは全面廃止
シングルトンそのものは1個
ただし、メンバには COM みたいの や boost::shared_ptr のような
グローバル的に使いまわしたいもの
各メンバは 実態ではなくポインタとし new してけば、生成/消滅はコントロール効く
シングルトンのコンストラクタで メンバの本体生成
シングルトンのデストラクタで メンバの本体消滅
フェニックスシングルトン使えば、破棄の順番とか考えずに・・・
フェニックスシングルトンとか名前超かっこいいよね
ゾンビシングルトン
>>727 基本的に、解放順序を気にするなら、その順序はプログラマが書かざるをえないでしょ?
mainの最初の行にCoInitialize
mainの最後の行にCoUninitialize
これじゃダメなん?
昔Direct3Dでstaticなメッシュを作っちゃって、どうしてもCoUninitializeの後にメッシュが解体されるという、実害はないがお行儀の悪いプログラム書いちゃったことあるよ。
でも、これってstaticなんて使った上で、さらに解放順序をうまくやってほしいってわがままじゃん?
なので素直に、staticじゃなくて、シングルトンかつ解放可能なクラスにしたよ。
んでCoUninitializeの前に開放メソッド呼んだ・;(`ε()゙
fstreamでUnicodeファイルを読み込むのはできないんでしょうか ANSI文字コードの時は読み込めるのですが Unicode形式で保存した時は、最初の読み込みで失敗判定が出てしまいます・・・・
>>733 wfstream
ロケール設定忘れんな
ぐぐったりして、一応こういうコードなんですが、一回目のget(w)でループが終了してしまいます #include <locale> #include <string> #include <iostream> #include <fstream> int wmain(int argc, wchar_t *argv[]) { std::locale::global(std::locale("japanese")); if (argc < 2) { return 1; } std::wifstream file(argv[1]); if (!file) { return 1; } std::wstring buf; wchar_t w = 0; while (file.get(w)) { buf += w; } file.close(); std::wcout << buf << std::endl; return 0; }
>while (file.get(w)) { buf += w; } while ( !(file.get(w)).eof() ) { buf += w; } これでどうだろう
(file.get(w)).eof()
C++には、プリミティブ型だけど、デフォルトコンストラクタのように書くと0を返す int i = int(); や、 関数みたいなキャスト int i = int(123.45); があると思いますが、 unsigned char uc = unsigned char(); とか、2単語以上使う型だとエラーになりました。 こういう型の場合はtypedefして使うしかないですか。 (そもそもあまり使われない書き方なのかな。
>>738 コンパイラやOSのバージョンくらい書こうよ。
>739 「C++には」から始まってるんだからまずは規格上どうかじゃないか? >738 規格(14882:2003)の 5.2.3 Explicit type conversion (functional notation) では simple-type-specifier って 書いてあるのでそのままだと多分無理。
VC++2008では通るな
あれって、template用だろ。 T i = new T(); で T がプリミティブな型でも通るようにって。 人間がそういうコードを書くためのもんじゃあんめえ。 キャストのほうは、むしろstatic_cast使えと。
>>700 文字列処理がうざいのでPerlで答え書いとく。勝手にCへ脳内変換してくれ。
sub hoge{
my $d = shift;
my $str = shift;
for(my $i = 3; $i <= 5; $i++){
my $a = substr($str, 0, $i);
if($i < 5 && substr($str, $i, 1) == 0){ $a = substr($str, 0, $i + 1); }
if($a % $d == 0){
for(my $j = 3; $j <= $i; $j++){
my $c = substr($str, $len - $j);
if($c % $d == 0){
my $b = substr($str, $i, $len - $i - $j);
if($b % $d == 0){ return ($a, $b, $c); }
}
}
}
}
return undef;
}
質問です a->b こういうのとかa.aa.aaaみたいなのをを大量ループの中で使う場合は いったんループの外で c = a->b とかしてループ中で使った方が速くなりますか? 別に気にしなくてもいいのでしょうか
気にしなくてもいい その程度のことは大抵コンパイラがやってくれる でもまぁ毎回 a.aa.aaa みたいに書くとウザイから、可読性の改善のためにやるのは良いかもしれない
#include <iostream> class A { public: void operator = (int) { std::cout << __FUNCTION__ << std::endl; } }; class B : public A { }; int main(void) { B b; b = 0; return 0; } コンパイルエラーになったんですがoperator=は継承されない仕様なんでしょうか?
>>747 B では暗黙のうちにコピー代入演算子 B& operator=(const B&) が宣言されるんで、
A の operator= が隠されてしまう。
B のほうで using A::operator=; としておけば両方使えるはず。
usingがありましたか operator= 〜{A::operator =〜}とかやりそうになってました レスありがとうございます
>>748 なんと!usingにそんな使い方があったのか。
protectedのメンバ関数を、派生クラスでpublic化するのに使えそうなんですけど、一般的ですか?
>>750 アクセス指定を変えるのに使えるのは確かなんだけど、
基底で protected とされているのを public にしてアクセス制限を
緩めるような使い方はたぶん一般的じゃない、っていうか普通に
考えればタブーの部類。 #define private public みたいな。
もしその操作が許されるなら、そもそも基底クラスの時点で public と
されているべき。
誘導されてきました。 電卓とカレンダー作りができる程度の初心者です。 基礎学習になるようなプログラムを組みたいのですが、何かおすすめの題材はありますか? また、ゲーム作りに興味があるのですが、少し調べてみたところ基礎的な学習とは方向性が違うように感じ、 基礎が身に付くまでは汎用的な学習がしたいと考えているのでチャレンジするかどうか迷っています。 ゲーム作りはC言語の基礎学習になるのでしょうか?この点についてもアドバイスをもらえたら嬉しく思います。 よろしくお願いします。
一通り文法が頭に入ったら習うより慣れろで実践あるのみ
電卓作れるレベルならもう基礎なんて十分じゃね?
>>753 どうもありがとうございます。宿題手伝いは思いつきませんでしたが、とても良い案に思えます。
手伝いとゲーム、検討してみようと思います。
>>754 はい、学んだ知識を使うことによって身につけていきたいのですが、
学んだものから何を作れるのかも分かっていないという情けない状況で、質問させていただきました。
>>755 非常に簡素な仕上がりの電卓だったので・・・。
自分が作ったのは、scanf関数で2つ数値を入力させ、switch文で演算子を選ばせて結果を出すという
簡易的なものでした。
電卓って思った以上に難しいからな。特に小数点以下。
>756 ゲームプログラミングなら 何らかのゲーム製作用のライブラリを手に入れて それを#includeすりゃ始まるさ。 ゲーム製作板だっけな、あの辺に行けば そういうライブラリを紹介してるサイトも見つかるかも知れないな。
入門書なんて楽勝!とおもってた俺もこの夏全部かけてもゲームの骨組みすら組みあがらなかったぜうわははははあーーーー
俺なんて1年半くらいやってるがまだ遊べるレベルに到達しないぞ
電卓で思い出したので便乗。 数式を入力できる、関数電卓のようなものを作るとする。 ちゃんと小数周りの計算とかもできるようにするなら 計算中はそれぞれの演算を分数の形で持っておいて、一番最後(出力時)に小数として出すのがいいのかな。
最後の行を訂正 それぞれの演算 → 演算項それぞれを
>>761 数式を組み立て直しておいて、パースから演算までを
外部プロセス(例えばawkのようなスクリプト処理系)に委ねるのも手。
マスマティカでおk
んじゃ、ActivePythonで。
おまいらwww
マジレスすると、電卓プログラムと数式評価は全く別物だね。 前者はGUIを巧く工夫すればJavaScriptでも手軽にできる代物だけど、 後者は二分木データ構造の典型的な課題になってるくらいだからね。
>768 マジレスするのは良いが誰にマジレスしてるんだい?
>>756 ブロック崩し
テトリス
シューティングゲーム
が簡単だと言われているが
作れる気がしないw
>>770 テトリスに限らず、落ちモノ系は結構きつい気がする。
STGは、最近流行りの弾幕ゲーとかじゃなくて、インベーダーくらいの認識。
あとは倉庫番とかアリじゃないかな。
アクション性のあるリアルタイム物はちょっと難しくなると思う。 敵が1体しか出ないターンベースのインベーダーとか練習にどうだろう。
ちなみに自分の最初の習作は壁打ちのPONGだった
そもそもC/C++にはリアルタイム入力を行える標準のライボラリがないからねぇ。
ゲーム作りたいならさっさとwindowsプログラミングとかに 手を出すべきじゃねーかなぁ。 モチベーションを保てるのがでかい。
プリプロセッサー の定義について教えて頂けませんでしょうか Visual Studio 2005 と、g++ (GCC) 4.2.4 のコンパイルスイッチ を付加したいのですがVC++ のコンパイルスイッチの設定方法は分かるのですが、 (ソリューションのプロパティページ→プリプロセッサ→プリプロセッサの定義で _USE_GCC などと定義する) foo.cpp とfoo.h があり、スイッチが_USE_GCC とした場合下記の方法だと、通りません? g++ -c _USE_GCC foo.cpp
そうしたいのですが、僕の買ったVisual Studio 2005 Universal Editionにはマニュアルがついていないのです。 どうしたらよいでしょうか。割れとかじゃありません。やばい。宇宙やばいです。
VC++だと/D_USE_GCCだっけ?
>>776 ,778
意味がわからん。
VC に USE_GCC を指定する方法はわかるんだよな?
今わからないのは gcc に指定する方法だろ?
だったら gcc のマニュアル嫁よ。
>>779 「VC++をコマンドラインで使う」なんて、絶対やったこと無いと思う。
だから当然、gccにオプションを渡す方法も知らないのだろう。
gccも、なんかIDEでも使ってるんじゃないかね。eclipseとか。
>>779 /D "_USE_GCC"と表示されてた
>>782 コマンドラインで使わなくとも、今の設定をそのままに、
コマンドラインからコンパイルするためのスイッチ一覧が表示されてたりするよ
msbuild使うならこれもいらないけどw
784 :
735 :2009/09/06(日) 13:11:14
>>736-737 やはり、一度目のfile.getでループがwhileから抜けてしまいました。
単にメモ帳で、ANSI⇔Unicodeを切り替えてるだけなんですが・・・
BOM読んでるんじゃ
質問です。 VC++9 xp です。 CEditに横長の文字列が入っていて、無理矢理複数行に改行されて表示するスタイルになっている場合、 横幅が先に決まっている状態で、高さをいくつにすれば全部表示しきれるのかが知りたいのですが、 これは可能でしょうか? よろしくおねがいします。
グローバル変数とexternって記述以外でどう違うんでしょうか?
>>784 そのtxtファイルをupして見せたほうが良いかもしれない
>>787 むしろどこが同じだと思ってるのか、と。
>>786 フォントとかテーマとか、関係するパラメータが多くて複雑なので、
(動的な)実測が一番楽だと思う。
実際に文字列を入れて行数を取得するか、
高さを変更しつつスクロールバーの有無を見るとか。
実測過程が表示されるのが嫌なら、別に用意した非表示のCEditでできないかな。
簡単にいうと externは 「どこかにある(グローバルな)変数を俺使うよ先生(実体はどこにあるか知らね)」 と宣言するためにある
>>792 「グローバル変数にしても」って言ってるところがすでにグローバル変数なわけだが。
あと、そこのページにあるインクルードガードは予約識別子を使っちゃってるから、
真似すんなよ。
externとstaticの2種類があってexternもstaticも付けないとexternの意味になる
>>796 ほう
int i;
これがexternの意味になるって?
>>796 そこらへん C か C++ かによる違いとか、いろいろもう少し複雑だから、
中途半端に言い切らないほうがいいよ。
リンケージでググるんだ 俺はググった事ないけど
子関数で使うんなら、ポインターか参照で渡せ。 子関数でなければ、それようのクラスでも作って、カプセル化してアクセスしろ
>>800 いらっしゃい。答えだけ言うなら引数で先頭アドレス渡せばよろしい。
#include <stdio.h>
int main(){
int a[5]={0,1,2,3,0}; f(a);
}
void f(int *ary){
printf("ary[4]=%d",ary[4]);
}
>>784 Windows付属のメモ帳だよな?
あれでUnicodeに変換するとファイルの先頭にBOMっていうデータが付加されるから
バイナリエディタとかで3byte削ってごらん。
以前sqliteの.readコマンドで1行目がエラーになった原因はそれだったから。
3byte?
3bytesだね。
2byteじゃなかったっけ?
0xFF 0xFE もしくは 0xFE 0xFF のいずれか?
UTF-8はEF BB BFの3byte UTF-16はFEFFの2byte UTF-32はFFFE0000の4byte
つーか元々の質問
>>735 を見てみたら、全然違う話じゃん。
UTF-8はwchar_tとは別物。多分メモ帳で変換したUnicode形式はUTF-8。wchar_tの
内部形式は処理系依存だが、UTF-8は可変長だから普通に考えると絶対使われない。
つまりI/O時に変換しないと駄目。
エントリポイントが wmain ってことは Windows ? Visual C++ の locale("Japanese") における wchar_t の挙動はキモかわいくて wchar_t をテクサコモードでファイルに書き出すと、Shift JIS に変換されちまうのだ。 そして Shift JIS を同じくテキサスモードで wchar_t に呼び出すと unicode に戻される。 結論から言うと、なんとラコステモードでは unicode ファイルは扱えないんだな。 ビッゲスト大弱り。
そもそもUnicodeでひとくくりにするから分かりにくくなる 少なくとも「変換の要らない夢のコード体系」なんてのとは程遠いから、外人が考えた アホらしい糞仕様をまずはちゃんと勉強汁
UTF-8のBOMって要らない子。
外来語を言い換えて遊んでる馬鹿って難なの? 面白いつもり? 自分をひけらかしているつもり?
815 :
811 :2009/09/08(火) 12:29:10
単にまじめに答えてやる気がないだけだよ。ゲラゲラ unicodeをWindows上で扱うのはやたら面倒なのだ。 ま、永遠に困ってろ。
メモ帳で"Unicode"を選ぶとUTF-16のBOM付リトルエンディアンになるよ "UTF-8"も選べるけど
なら2byte削ればokなのかな
ずっとucs-2leだけだとおもってた。 いつの間にかutf-8に対応してたんだ? やっぱメモ帳侮れないな。(euc-jpはイツデスカ。。。)
819 :
デフォルトの名無しさん :2009/09/08(火) 13:52:32
class IntArray2D{ public: IntAttay2D(int size0,int size1): mArray(0), mSize0(size0), msize1(size1){ mArray=new int[size0*size1]; } ・ ・ ・ 本に書いてあったコードなのですが このような書き方になじみが無く何をしているのかよくわかりません mArray(0), mSize0(size0), msize1(size1) は何をしているのでしょうか?
mArrayを0で初期化している のこりも同様
初期化子というもの
822 :
デフォルトの名無しさん :2009/09/08(火) 14:20:57
constメンバの初期値なんかには必須だな
>>818 >euc-jpはイツデスカ。。。
永遠にお待ちください。
>>815 Windows以外なら簡単というわけでもないだろ。
Localeに詳しくない人は「I♥NY」をファイルに出力することもできないわな。 そのくらいUnicodeの扱いは難しい。
ポインタを使って参照渡しというものをやってみたのですが うまくうごいてくれません。どこが間違っているのでしょうか? 一次元の配列では上手く動きました 数値を配列aに代入し、f関数で配列aの4番目の要素を表示させるというコードです #include <stdio.h> void f(int *ary); int main(){ int a[5]= {0,1,2,3,99}; f(a); } void f(int *ary){ printf("%d",ary[4]); return ;} ですが二次元配列にするとダメです。どこが間違っているのでしょうか? #include <stdio.h> void f(int *ary); int main(){ int a[2][5]= { {0,1,2,3,99}, {5,62,6,3,99} }; f(a);} void f(int *ary){ printf("%d",ary[4]); return ;}
void f(int ary[][5]);
int a[2][5];はint **a;に相当するから。 int main() { int a[2][5] = {...}; f(a[0]); }
おいprintfでbool型をtrue/false表示するにはどうしたらいいですか。
printf("%s", b?"true":"false");
>>831 printf("%s", b?"true":"false");
なるほど。それでできますね。天才ですね。 %sの部分でbool型を指定するようなことは文法的にできないのかな。
>>834 ライブラリの仕様的にない。
まぁ自分でprintf的なものを作り直せばあるいは、程度かな。
C++ならboolalphaってフラグあるんだけどな
参照はがし と 逆参照 って同じ操作の別名ですか?
>>837 どちらも「デリファレンス」 "dereference" の訳語のようで、同じかもしれないけど、
文脈によっては違うかもしれない。
>>838 ありがとうございます。おっしゃるとおり、両方共翻訳された本にでてきた表現です。
構造体を定義して、別フアイルで使いたい場合はどうすれば良いでしょうか? ↓は構造体の型"hito"を定義し、hito型の変数"hitorime"をnormal関数で使いたいのですが使えない状態です。 宜しくお願いします。 //main.cpp #include "kozo.h" int main(){ normal (); return 0;} //normal.cpp int normal () { extern int aaa; extern hito hitorime; } //kozo.h void normal(void); int aaa; struct hito { int x; int y;}; hito hitorime;
>>837 「逆参照」って、ほんとにわかりにくい言葉だよな。
何が「逆」なんだか。
ポインタの指している先を扱うのにもっとわかりやすい言葉はないもんかね?
実体って言ったいけど、間違ってる?
>>840 //normal.cpp
struct hito {
int x;
int y;};
void normal () {
int aaa;
hito hitorime;
}
//kozo.h
void normal(void);
int aaa;
struct hito {
int x;
int y;};
//main.cpp
#include "kozo.h"
int main(){
normal ();
return 0;}
846 :
845 :2009/09/10(木) 16:56:45
あー、しまった。テキトーにコード書くもんじゃないな とりあえずstructの宣言は同じファイルに無いと× kozo.hインクルードしとけ
847 :
デフォルトの名無しさん :2009/09/11(金) 16:57:32
Linuxだとvectorのvectorはダメなんでしょうか? FreeBSDだと通っていた下のコードがコンパイルエラーになります。 #include <iostream> #include <vector> using namespace std; struct Zoo { std::vector<std::vector<int> > animals; }; int main (int argc, char** argv) { Zoo ueno; return 0; } 誰か助けて><
エラーメッセージは?
std::vector<std::vector<int> > animals(1, std::vector<int>()); あとはresize()メンバ関数で拡げる
850 :
847 :2009/09/11(金) 17:14:09
>>849 それで解決しました。ありがとうございました。
きちんと型を指定したら通りました。それぐらいコンパイラが察してくれてもいいと思います。
文句いうな C++標準化委員会が決定した初期化オプションだ
練習がてら std::vector<std::vector<std::vector<std::vector<int> > > > はどうやって初期化すればいいか書いてみろ
>>852 今までの流れに全然関係ない者ですが、
初期化の記法について今までなあなあにして来ました。
ここいらで勉強しようと思っているのですが、
どのあたり(サイト等)を参考にするのが良いでしょうか?
あー標準C++ライブラリ(絶版)買わなかったのかよ 仕方ないな古本屋で探すか規格票買え
>>855 そりゃ規格違反のコンストラクタを備えているな
それともC++0xの機能でも取り入れてるのか?
858 :
857 :2009/09/11(金) 19:56:13
Comeau C/C++ Online の方では、もちろん Compile in strict C++03 mode Disable C++0x extensions のモードでやったよ。
>>856 std::vector<int>はデフォルトコンストラクト可能だから847はどこも問題ないように自分は思う。
エラーになる理由を教えて欲しい。
通るわな
>>852 は後からresizeを使う回数を減らすために
行方向に個数を指定する時に使う
vector< vector< T > > vec2d; vec2d.assign(size1, vector< T >(size2, init)); と vector< vector< T > > vec2d(size1, vector< T >(size2, init)); って大差ないよね?
>>863 ただの間違いだろう。
・・・いやあってるのかな。
>>862 それだけ見ると、前者は間抜けで後者は普通。
>>863 自分もわからん。
>>847 は Zoo 構造体のオブジェクトを宣言したくて
でもなぜか データメンバとして std::vector<std::vector<int> > のような型(vectorのvector)があると
Linuxではエラーが起きるといってるようだけど
ここにはコンパイラがなんなのか、どんなエラーが出たのかも書いていないから、
本当に、データメンバの型が原因でエラーなのか特定できない。
大体、
std::vector<std::vector<int> > animals(1, std::vector<int>());
は Zoo 構造体のオブジェクトじゃないから、
>>847 の意図することはまったくできてない。
あ、いやすまん、 std::vector<std::vector<int> > animals(1, std::vector<int>()); を ueno と勘違いしていた。 最後の3行は忘れてくれw
コンパイラとエラーメッセージぐらい書いてよね
構造体・クラスはintやdoubleのように関数の外に書くだけでグローバル変数にできるんでしょうか?
そうだよ。intもdoubleもクラスも構造体もその点で平等。
LinuxだのFreeBSDだのじゃなくて単にg++が古いとかその程度の問題だろどうせ
#include <cstdio> で sprintfがグローバルスコープに宣言されるようですが、 std::名前空間にも宣言されているようです。 両方に宣言されるものなのでしょうか?
わからないことがありました!! なんらかの関数で! 質問1 1.txtから10.txtまで一気に開きたいとします! だけど、例えばそのパスを指定するときが文字列である場合、 ""で囲んでしまうので、変数で指定できないと思いました! この場合はどうやって一気にしていすればいいの! 質問2 a.txtからf.txtまで一気に開きたいとします! この場合も上記と同様な問題が発生します! どうすればいいの?!!! 教えて!!!!!!!!!!!!!!!
>>875 とりあえず自分で書いて、何が不満なのか明らかにしろ。
>>876 やったけどわかりません!!!!!!!
わからないから教えて!!!!!!!!!
>>877 それ以外!!!!!!!!
それ以外で!!!!!!!!
sprintfを拒む理由は
>>875 for (i = 0; i < 10; i++) {
sprintf(path, "%d.txt", i + 1);
fp[i] = fopen(path, "r");
}
>>880 その方法以外で!!!!!
だってその方法じゃ今後Win32APIでプログラムするときに結局またぶちあたる!!!!!!
それやっぱ根本的解決ちゃうで!!!!!
>>881 意味がわからねえ。
Win32apiと標準関数は併用できないって思ってるのか。
うぜぇな Win32でもこの方法で行けるんだよ
まぁこの程度のやつがsprintfとか使ったら確実にバグだらけ
そういうやつでもCString::Format使えばいくらか問題を起こさないで済む確率が上がると思う。
wsprintfだったらWinAPI関数だよ 標準C/C++では使えないけど
>>881 ぶちあたらないから大丈夫やで!!!!!
変数ヲヘッダファイルで宣言すると、使えなかったり、定義は既にされていますなどのエラーが 頻繁に起こるようになってしまいました ファイルを分割したときの注意点をまとめたようなサイトとかありますか?
まず宣言と定義の違いを調べるのがいいかと
分割コンパイルでググればよかろうっ!!
allocatorって何者なの?
わたしです
ぐぐったほうが早くて正確と思う
boostにも手作りのアロケータがあってそれをSTL標準の アロケータに食わせると微妙に速度が異なる 大抵遅くなるw
アロケータはC++標準では模倣できない参照を 再定義する仕様になっているので ライブラリ標準のアロケータは大概アセンブラで書かれて
>>875 stringstreamとかsnprintfとか使えばいいんじゃないの?
899 :
デフォルトの名無しさん :2009/09/13(日) 23:42:24
猫でもわかるC言語を一通り読み終わった程度の初心者ですが、質問をさせてください。 開発環境はWindowsXPでBorlandのC++コンパイラを使っています。 作りたいソフトの勉強の為、簡易なヴォイスレコーダを作ってみたいのですが 参考になる様な本やサイトがググっても見つからず、途方にくれています。 どなたか音声処理(?)のプログラミングの参考になる様な本やサイトをご存知の方 いらっしゃいましたら、どうか教えてください。よろしくお願いします。
>>899 winmm.lib系のAPIでいいならWebで使い方が見つかると思う。MSDNとか。
waveInOpenあたりで検索すれば出てくるんでないか。
901 :
デフォルトの名無しさん :2009/09/14(月) 00:25:23
このように書けるよう、= 演算子のオーバーロードの書き方を教えてもらえないでしょうか。 char* ch; std::string str; ch = str; 環境vc8
>>901 無理。これくらいで我慢しろ。
const char* ch;
ch = str.c_str();
>>901 左辺の型に代入演算子を定義できないか → (char*)は自作クラスじゃないのでいじれない
右辺の型に変換演算子を定義できないか → std::stringは自作クラスじゃないのでいじれない
演算子をstatic関数として定義できないか → 代入演算子や変換演算子は、static関数にできない
なので答は
>>902 だな
template<typename CharT, typename Traits = std::char_traits<CharT>, typename Allocator = std::allocator<CharT> > class basic_stringex : public std::basic_string<CharT, Traits, Allocator> { public: operator CharT*() const { return const_cast<CharT*>(c_str()); } }; typedef basic_stringex<char> stringex; char *ch; stringex str; ch = str;
>>899 よほどの理由が無いならBCCを捨ててVCEEにした方がいい。
BCC推奨してたとこを見たなら多分情報が古い。
>>901 まぁ、単にコーディングの練習がしたいのかもしれんが、そういう設計は危険。
型変換じゃなく、標準ライブラリのようにc_str()みたいな変換用のメンバ関数を作れ。
=だのキャストだのは、意識してない場面で勝手にコンパイラが他の用途に使うことが
あるから、その辺をガチで把握してないと迂闊に使えないし、把握してくると下手に
使うもんじゃないことも分かってくる。
>>905 それ以前にconst付いてないんだぜ。
つまりstd::stringの中身をそのままいじらせろってことだ。
>>907 そうとは限らんぞ、コピーを貰うのでも満足するのかもしれん
まぁどっちにしろ、operator=で書くべきではないことに変わりはないが
>>901 です
皆さんありがとうございます。template <class X, class X2, class X3, class X4, class X5>
struct some {
X x;
X2 x2;
X3 x3;
X4 x4;
X5 x5;
};
some<char*, char*, char*, char*, char*> s;
s.x = 色々な型の変数;
s.x2 = 色々な型の変数;
省略〜
そもそも、このような型に依存しない構造体を定義して、あらゆる型が
= 演算子をオーバーロードできないかと思った次第でしたが無理なようですね、ありがとうございました。
char* 型の場合とかはtemplate の特殊化するとかで、できないもんだろうか・・・・今の自分では力不足ですorz
この辺を使うとか
http://www.kmonos.net/alang/boost/classes/any.html http://www.kmonos.net/alang/boost/classes/variant.html メタプログラミングと共用体を駆使して型を消去する手法もある
union var
{
private:
int int_;
float float_;
public:
template<typename T>
void set(enable_if<is_floating_point<T>,T>::type x){float_=x;}
template<typename T>
void set(enable_if<is_integral<T>,T>::type x){int_=x;}
template<typename T>
void get(enable_if<is_floating_point<T>,T&>::type x){x=float_;}
template<typename T>
void get(enable_if<is_integral<T>,T&>::type x){x=int_;}
};
こんな感じに
ああすまん、enable_ifのとこにtypename忘れてた void set(enable_if<is_floating_point<T>,T>::type x){float_=x;} ↓ void set(typename enable_if<is_floating_point<T>,T>::type x){float_=x;} こんな感じに直せ
まぁ、実のところ、
>>901 が何をしたいのかいまいち分からないんだけどな。
>>911 の手法は、入れた時の型で取り出さないと正しい情報じゃなくなることが
あるから注意。stringを入れてchar*で取り出せる、なんて夢を見ちゃ駄目。
というか、素でそういうことのできる言語じゃない。そういうことを手軽に書ける
ようにしたければ、手間と知識が要る。
逆に、そういうことを気にしないでいい言語というのは、最初からそういう重たい
安全装置がガチに装着されてるってこと。だから、重さを気にしない、すぐに仕事
を済ませればいいというような用途なら、そういった言語を使う方がいい。
もし「stringとchar*をある程度同じように扱える場面を作ろう」としているなら、
それは典型的なアンチパターン。初心者が自分でわざわざ作っては踏む地雷。
914 :
デフォルトの名無しさん :2009/09/14(月) 13:25:45
VC++2008EEで、リリースビルドでランタイムライブラリを マルチスレッドDLLにすると例外が発生します。 マルチスレッドデバッグDLLにすると発生しません。 リリースビルドは最適化等は全て無効でプレーンな設定です。 調べてみると、std::setのコンストラクタ内で例外が発生しており、 ファイル名:xtree 行数:1325 return (_Parent(_Myhead)); ↓逆アセンブル結果 1020EE1C 8B 45 FC mov eax,dword ptr [this] 1020EE1F 8B 48 18 mov ecx,dword ptr [eax+18h] _Myheadはメンバ変数で、アドレスはthis+0x04なんですが、 ここでオフセットとして0x18を足してるのが原因みたいです。 マルチスレッドデバッグDLLだと、アドレスはthis+0x14になり、 オフセットとして0x14を足すので、正しく動作します。 なぜこうなりますか?どうすれば直るでしょうか?
リリースビルドで最適化を切ってSTL使ってるだと…? まぁバグには関係ないだろうけど
もしかしたら関係あるかもね。 いずれにしても、リリースビルドで最適化を切るなんてのは狂気の沙汰にしか思えないけれど。
917 :
914 :2009/09/14(月) 13:49:32
最適化は、問題を探る為に切っています。
std::setで扱っているクラスのソース希望。 まさかとは思うけど、フルリビルド位しているよね?
>>918 フルリビルドはしています。名前は変えていますが、これがソースです。
このXのコンストラクタ起動 -> m_recordsのコンストラクタ起動で落ちます。
m_recordsの初期化にまつわるコードは何もありません。(暗黙のコンストラクタ呼び出し)
class X {
public:
typedef boost::variant<
boost::shared_ptr< A >, boost::shared_ptr< B >, boost::shared_ptr< C >, boost::shared_ptr< D >,
boost::shared_ptr< E >, boost::shared_ptr< F >, boost::shared_ptr< G >, boost::shared_ptr< H >
> Record;
typedef std::set< Record > RecordSet;
private:
RecordSet m_records;
boost::variantを取り除いて落ちなくなるなら、それが原因。
boost::variant使ったこと無いからなぁ… C++0xならunionにしちゃえって話になるのかもしれないけど。 とりあえずその八つのshared_ptrの指す型を消したいように見えるけど、結局は boost::variantも中で仮想関数を持つようだし、自前でその八つのクラスを多態 にしてみる手はあるんじゃね?
boost::variantは内部のデータ構造どうなってるんだろ? STLが受け付けないような作りになってるのかな?
924 :
914 :2009/09/14(月) 15:47:06
variant無し版を作って試したところ、同じ結果でした。 やはりオフセットを0x04にしなければならないところが 0x18になっていました。んー謎です。
リリースビルド(ただし最適化無し) と デバッグビルド゙ とでメンバへのオフセットが変る メンバの再配置起きてるのかもしれんけど RTTI 有り/無し が関係してたりするのかな?
boostの未知のバグかもしれんな
variant無しでもそうなるのか いや、というか、無し版のソースもくれ
929 :
914 :2009/09/14(月) 16:50:54
どうも std::set< boost::shared_ptr< A > >も同じようにずれるように見えます。
あんまり自信がないので、これからもっと調べてみます。
試しに同じクラスに置いたstd::set< int >は、ずれないようでした。
>>927 入っていないようです。入れてみます。ありがとうございます。
>>928 出すのはちょっと難しい、、、
やっていることは構造体に、boost::shared_ptr< n >を並べているだけの
単純なものです。
930 :
914 :2009/09/14(月) 18:22:21
どうやらstd::set< boost::shared_ptr< A > >も同様に失敗しているようで Aの種類によって現象が起きたり、起きなかったりするようです。 起きるものどうしの共通点は特に見当たりませんし、 何か特別変な構造にしている訳でもありません。 set< boost::shared_ptr< A > >では問題が起こるものの、 set< A >では起きなかったりと、よくわからない感じです。 それで、諦めました。VC++2010で直る事を期待します。 お付き合い頂いてありがとうございました。
コンパイラのせいにしてるうちは直らないゾ setやvariantにshared_ptrはさんざん使ってるけど問題なんか起きないけどね。 リリースされて時間が経ち多くの人に使われているコンパイラとライブラリと、 今作ったばっかりの自分のプログラムをどっちを疑うかかって言うと、やっぱり 自分が作ったばっかりのプログラムを疑うけどな。俺は
>>922 型を示すインデックスと、インスタンスを保存する領域からできていて、placement newしてる。
STLでも問題なく使える。
>>931 俺もいくつかvcのバグみつけてるから、
>>930 のソースが悪いとは言い切れないんだけど
追試できるものをくれないとその結論になっちゃうよねぇ
文字列の型変換について教えてください。 std::string に格納した文字列(恐らくSJIS)を、 CString などのUNICODEを格納する型に変換したいです。 何か変換関数があるのか、それともキャストでどうにかなるのか知りたいです。 よろしくお願いします。 ※開発環境はVS2005です。 ※UNICODEを使用する環境にしています。
>>934 c_str()メンバ関数にしてchar文字列拾って代入したらだめなん?
>>935 迅速な回答、ありがとうございます。
教えて頂いた内容を試してみます。
>>934 ,936
MultiByteToWideChar
>>935 マルチバイト文字はそれでは無理。
UNICODEのCStringって、マルチバイト文字を代入したら、自分でワイド文字に変換してくれなかったっけ?
CStringなら変換コンストラクタとoperator=があるじゃん。
c_str()って書いてたから
質問です GameInfo() :m_gameType(0) ,m_id(-1) {} こういうタイプの初期化を行う場合、メンバー配列変数の中身を初期化する方法はありますでしょうか?
>>941 デフォルトコンストラクタの初期化でよければ、引数なしにすればオーケー
GameInfo() : m_array() {}
WindowsAPIのイベントハンドルの質問なのですが、 WaitForMultipleObjectで待機中に、別スレッドで イベントハンドルをCloseしてしまうと問題があるでしょうか? HANDLE h[2]; h[0] = event_1; //イベントは初期化済み h[1] = event_2; WaitForMultipleObject(2, h, FALSE, INFINITE); //この待機中に別スレッドでイベントの一つをCloseHandle(片方だけ)
>>945 ありがとうございます。
復帰必須なんですね。
SetWindowTextでタイトルを変更すると、XPスタイルの時のみタイトルの文字の位置がおかしくなります。 具体的な症状は文字列が一段落上の位置に表示されてしまうんです。 VistaやWindosw98スタイルでは正常な位置に表示されるのですがXPだけおかしくなっちゃいます。 どなたか原因が分かる方はいませんか?
ポリシークラスからホストクラスのメンバを参照したい場合って仮想関数使うのが正解なんでしょうか?
Modern C++ design じゃないの? Policyとか言ったら
そうなると仮想関数とか概念的にかすりもしない感じで、やっぱり ESP が足りない。
>>948 ポリシークラスは、ホストクラスからアクセスされるクラスであって、
ポリシークラスからホストクラスにアクセスするのは設計が良くないと思う。
ポリシークラスで必要になるデータは、ポリシークラスのメンバ関数の引数で受け取るようにするのが無難。
どうしてもホストクラスにアクセスしたいというなら、仮想関数しかないね。
以下個人的に思う事。
Policy設計は、ポリモフィズムが必要なケースには向いてないと思う。
STLやboostのような汎用的なライブラリを作るのに向いてると思う(趣味グラマではそういうケースがほとんどない)。
template<class Writer> class Hoge : public Writer {   list<int> data_; }; struct Writer {   void Write(); // どうにかしてdata_を取得して出力 }; Hoge<Writer> h; h.Write(); こういうのは悪手ということですかぁdです 本読んだときはなんかすごいと思ったんだけど実際やってみようとすると 難しい割りにうまくいかなくてしょんぼり・・・
template<class DataType> struct Writer { void Write(const DataType &data); }; typedef Writer<std::list<int> > Writer_IntList; template<class Writer_IntList> class Hoge : public Writer_IntList { std::list<int> data_; }; こんな感じかなあ
自己言及テンプレートは普通、 template <typename T> class base { public: T foobar(); } class derivedA : public base<derivedA>; こういう構成な気がするが…
かぶった予感
957 :
デフォルトの名無しさん :2009/09/16(水) 17:18:05
クラスというものを少しずつ覚え始めたんですが、 C言語に移植するんてことを考えない限り、構造体や関数を定義するより なんでもかんでもクラスにしてしまったほうがいいんでしょうか?
ケースバイケース
959 :
デフォルトの名無しさん :2009/09/16(水) 17:55:30
うーん、そうですか。ありがとうございますた
基本的にはクラスでやるもんじゃねーの?
ケースバイケース
関数で色々作っておいて、後からそれらを使ってクラス化するほうが 大抵失敗しない気がする。
情報単位じゃなくて処理単位だよね 初期のC+オブジェクトな考え方を大声で吹聴するジジイどもは早く引退してくれ
>>954 template<class DataType, template<class> class Writer>
class Hoge : public Writer<DataType>
{ DataType data_; };
こうじゃないかな。
>>957 構造化プログラミングもOOPもその他のパラダイムもできてしまうのがC++の柔軟さであり、罠でもあるところ。
柔軟に使いこなせればベストなんだろうけど、OOPだけを考えて作った方が失敗が少ないかもしれない。
OOPだけ考えて作ると、例えばソート処理とかひどいことになるんじゃね?
ソートするなら、構造化まで戻るか、総称型まで進むか、かな メソッドや継承だけでどうにかしようとは思わないな
>>965 STLとboostは使うべきだと思う。
OOPで作るのが難しい物ってそうもない気がする。
まあ、ゲームなんかは物によってはOOPで作るのが難しいかもしれないが。
少なくとも学生が使っていいもんじゃないと思う。
「OOPじゃオーバーキルだ」という場面と「OOPじゃ機能不足だ」という場面が ある。 前者は、構造化くらいで十分適切なところを無理にOOP化しても、という考え方で、 これに対しては「別に全部OOPでいいよね」って話になる。(Applicationクラスを 作ったりObjectクラスを作ったりするのはやりすぎだけど) 後者は逆に、ジェネリックプログラミングとかメタプログラミングとか便利じゃん、 という考え方で、こっちは「OOP縛りじゃ時々困るよ」って話になる。 この二つの話が混乱してる気がする。
>>969 > 「OOPじゃオーバーキルだ」という場面と「OOPじゃ機能不足だ」という場面が
「OOPじゃ役不足だ」という場面と「OOPじゃ力不足だ」という場面が
でいいのに、オーバーキルとかゲームする人じゃないと通用しなくね?
普通の英語じゃね? IT関係の記事とかにも使われてるじゃん
>>969 前者も後者も開発効率を問題にしているという意味では同じでしょ。
C言語が手続き型しかできないからといって、作れないプログラムがあるわけじゃない。
俺が言いたいのは、適切にパラダイムを選んで柔軟に書く能力があればベストだけど、
経験の浅いPGにとって、選択肢の多さは良くない設計を選ぶリスクの増加になってるんじゃないかという事。
>>967 boostと出会ったおかげでSTLを使う気になった。STL単独では使う気にならないな。
>>974 前者もランタイム効率は変わるぞ
というか、基本は手続き型、必要ならクラス、必要ならジェネリック、必要ならメタ、
ってそんなリスキーかね?
全部クラスにする方がリスキーだと思うけど
STLだとVCでテストしてる時に、IDE上で中身が簡単に見れるから使う 自作listだと、わざわざnextポインタから開いていかないといけないからメンドイ
懐かしいなw俺もクラスに目覚めた頃は
>>957 だった
実際、一人で開発するならそれもいいかもしれない
もう少しプログラムを作りまくれば、ケースバイケースが見えてくるだろう。
あえて言うなら趣味でも、時間的な区切りをつけてみるといい。プログラムの効率をもっともっと考えれるようになる・・かもしれない
>>974 パラダイムの違いによって出るランタイム効率の差なんて問題にならないレベルでしょ。
>>975 これを言ってはおしまいだが、C++がリスキーだと思う。
いろいろできるC++より、制限の多い言語の方が初学者向きという意味で「OOPだけ〜」と言った。
熟練したPGがC++をどう使うべきか、は宗教論争にしかならないんじゃない?
何だ、C++を覚える時にいきなりOOP縛りの方がいい、って主張してるんじゃなくて、 OOP縛りの言語に乗り換えろって意味だったのか。 初心者だろうが熟練者だろうが、C++を使うなら最初から最後まで、必要なところだけ OOPという使い方で十分だろ。 C++以外の「制限の多い初学者向き言語」の話はどうでもいい。
なんかやらしい言い方をしてるな できることが多くて混乱してしまう可能性があるから、使い方を制限して慣れてみたらどう?と言ってるんだろうと思うよ。 制限するくらいなら制限された言語を使えばよろしい、というのはもっともだけれど、ここはC/C++スレ。
>>975 たいていのプログラムはデータをどうにかするものなんだから、
基本はクラス、必要なら手続き型、ジェネリック、メタ、
でよくない?
>>979 OOP縛りの方がいいと主張してる。
なぜOOP縛りの方がいいと思ったか、理由を説明するために他の言語の話を出した。
> 初心者だろうが熟練者だろうが、C++を使うなら最初から最後まで、必要なところだけ
> OOPという使い方で十分だろ。
「必要なところだけ」とは言うが、全部Cライクで書くこともできるし、全部OOPで書くこともできる。
必要不必要の判断基準なんて人それぞれで、議論しても宗教論争になるだけだと思うんだが。
他人がどういう判断基準持っていようがケチつけるつもりはないよ。
>>957 の質問に対して自分の考えを述べたまで。
すべての根底となるクラスが存在しない時点で、C++を用いた完全なOOPは 不可能であるという、一つの結論が出てたような
完全の定義がよく分からん。
エントリポイントを 変えれば いいじゃない
> 全部OOPで書くことができる
俺はこれがもうわからんのだが、
>>984 はどう
基底クラスがない代わりにテンプレートを作ったのかもしれないと今思ったが、どうなの
>>983 不完全を証明するにはただの1例を示せばよい。
具体例をどぞ
とりあえずそのエントリ変えた完全なOOPとやらがどうしようもない糞コードなのは間違いないが
C++でもOOP縛りがいい、という主張には全面的にNOだな。 「OOPより簡単な物じゃ駄目だよ」と「OOPより複雑な物は初心者には要らないよ」を 同時に主張しているが、OOPは銀の弾丸じゃない。 昔よく見たような「OOPは難しいから初心者は全て手続き型でいいよ、でも構造化は 絶対に習得しようね」というOOP知らずな連中の甘言をそっくりそのまま一段進めた だけにも見える。 大体、初心者を馬鹿にしすぎ。
本人が実際に両方やりゃ勝手に分かるだろ どうせここでは結論なんか出ない
旧世代なオッサン怒涛の逆襲来たー
柔軟に適切な選択をするのは難しいから、OOPと手続き型がどっちが良い? と言うのであれば、俺の主観だと OOP3 : 手続き7 くらいの割合を選ぶ。 4:6くらいでも良い。 OOP主体だと汎用性を高めようとして記述量が増えるか、インターフェースが ゴタゴタで使い手側が気をつけないと危険な物になる印象。 それらを乗り越えるためにあえてOOPの練習するのも良いかもしれないが。
「OOPL」と「手続き型」は背反しませんが。
OOP無しの構造化だけのパラダイムを指してるんだろ常考
初心者だからと言って、OOPなんて古典的なやり方だけに閉じこめる理由は無いだろ
次スレは?
なし
そして
伝説へ(パラダイム的な)
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。