【初心者歓迎】C/C++室 Ver.50【環境依存OK】
1 :
デフォルトの名無しさん :
2008/02/28(木) 00:01:39
だぶった
3 :
デフォルトの名無しさん :2008/02/28(木) 00:05:35
かっこいいって何だよw こっちが遅いから、あっちが先だな。
1乙です。 こっちもいいな〜
6 :
デフォルトの名無しさん :2008/02/28(木) 00:09:53
再現はさせられないけど・・・これだと一致してしまう #include <iostream> #include <string> using namespace std; main(){ int n, sz=1024*100, step=8; string c(sz,'\0'),x="", y(sz,'\0'); for(n=0;n<sz;n++)c[n]=rand(); for(n=0;n<sz;n+=step){ x+=c.substr(n,step); memcpy(&y[n],&c[n],step); } if(x==y)cout<<"一致しました"; else cout<<"異なります"; }
まあ同じになるだろうな。 そうやってメモリをちゃんと確保してるなら問題は無い。 string は実は 0 を含むことができるしね。 (string += const char* としようとすると const char* の 0 が現れた時点で代入が止まるが) 現状の規格では string の内部バッファの連続性は保証されてないけど、 次期規格で保証されるようになる位一般的な実装だから心配は無いだろう。
前スレ965,966様 よくわかりました。自分が馬鹿でした。ありがとうございました。
Visual C++ の質問です。 選択した画像ファイルのヘッダ情報?(フォーマット、カラースペース等)を 取得するにはどうすればいいのでしょうか 質問の意味が分からなければごめんなさい。 始めて右も左も分からないもので… よろしくお願いします。
>>9 画像フォーマットに応じてヘッダ解析処理を書く。
画像フォーマットの仕様書はネット探せばあるだろ。
こっち使うのか。 まあかっこいいからしょうがないか。
コンストラクタでインスタンスの生成が始まって 実際にメンバ関数や変数が使えるようになるタイミングというのは気にしなくて良いのでしょうか? あと、派生クラスの時には仮想関数はコンストラクタ内で使用しない方が良いというのは本当なんでしょうか?
>>13 >実際にメンバ関数や変数が使えるようになるタイミングというのは気にしなくて良いのでしょうか?
どういうときに気にする必要があるの?
>コンストラクタ内で仮想関数
ケースバイケースだが、派生クラスでオーバーライドされたものが呼ばれると思ってると痛い目に会う。
>>13 >あと、派生クラスの時には仮想関数はコンストラクタ内で使用しない方が良い
>というのは本当なんでしょうか?
C++のオブジェクトモデルの観点から言えば、
少しおおざっぱだが(厳密さは省く)、コンストラクタにはコンパイラ
によってvptrが自クラスの仮想関数テーブルへのポインタにセットされる
タイミングがあって、コンストラクタボディでは既にセットされてしまって
いる。基底クラスのコンストラクタボディでは基底クラスの仮想関数テーブル
が参照される。どう頑張ってもポリモルフィズムは起こらない。
もしも仮想関数が純粋仮想関数だった場合にはどうなるんだろ 基底クラスには存在しない関数を呼び出すことになるので コンパイルエラーになるのかな?
18 :
16 :2008/02/28(木) 14:54:58
>>17 どうもです
g++でテストしてみたよ
エラーになった…コンパイルエラーっぽいけどリンカエラーなのかな
詳細は不明ですが、エラーになると。まあ当然ではありますが…
>tes.cc: In constructor `A::A()':
>tes.cc:12: error: abstract virtual `virtual void A::func()' called from constructor
>>18 認識合ってないかも。
>>13 からの流れのだよね?
class Widget {
public:
virtual void jyunsui() = 0;
Widget(){ jyunsui(); }
~Widget(){}
};
class Budget : public Widget {
public:
void jyunsui() {}
};
Budget b;
こういうことじゃない?
20 :
16 :2008/02/28(木) 15:13:34
>>19 コンストラクタから仮想関数を呼び出すときに仮想関数テーブルにある
関数が呼び出されるという話を聞いて
仮想関数が純粋仮想の場合はどうかなと思った次第であります
あまり深い意味はありません、すみません…
テストしたコードは19さんのコードと同じです
コンパイルすると
>tes.cc: In constructor `Widget::Widget()':
>tes.cc:8: error: abstract virtual `virtual void Widget::jyunsui()' called from constructor
>>20 へえ、コンパイルエラーなんだ。
Comeau C++ では警告は出たけどコンパイルできた。
VC++2008だとリンクエラーになったね。
定義すると警告無しでビルドできた。
処理系に依存するのか。。
VC++2005で "1.wav"などローカルに保存された音声ファイルを再生したいのですが。 標準でそういった関数?はあるのでしょうか?
PlaySound()なんていう便利なAPIがあるとか本気で思ってるの!?
>>20 g++ 4.0 では警告出たけどコンパイルできたよ。
もちろんリンクはできないけど。
定義するとリンクも通る。
27 :
デフォルトの名無しさん :2008/02/28(木) 18:45:23
すいませんお願いします。 passing `const cell' as `this' argument of `double cell::cell_input(double)' discards qualifiers というエラーが出ます。 問題の行は IT->first.cell_input( OUTPUT*(IT->second) ); でITは map<cell,double >::iterator IT; です。 やりたいことはclass cellのオブジェクトA内のpublic関数から 別のオブジェクトB内のpublic関数にアクセスすることです。
>>27 map<cell,double >
のcellはconstで修飾されてる。
IT->first.cell_input・・・・
cell::cell_input(double);が非constメンバー関数なんじゃないの?
C++の質問です。 コンパイラはbccを使用しています。 別のcppファイルで定義した配列をexternしたいのですが、 "外部シンボルが未解決です"というリンクエラーがでます。 data.cpp const char namber[5] = { 1, 2, 3, 4, 5 }; show.cpp extern char namber[]; リンクエラーを解決する方法を教えて頂けないでしょうか? よろしくお願いします。
30 :
デフォルトの名無しさん :2008/02/28(木) 19:05:53
>>28 ありがとうございます!
非constメンバー関数、で検索かけて調べてみます!
31 :
27 :2008/02/28(木) 19:17:50
すいません。。 調べましたがmapに放り込んだ時点でconst cellになってしまうから もし非constメンバ関数からconstメンバ関数に変えられない場合 私がやりたいことは出来ないということでしょうか? cell_ouputは非constメンバ関数でありデータメンバを書き換えます。
>>31 残念ながらmapのキーはconstだからキーのオブジェクトは
変更できない。他の手段を考えたほうがいいかも。
とにかくcellはconstオブジェクトだから非constメンバー関数
は呼び出せない。
>>31 変更する部分をまとめてpimplにするとかはどうよ?
34 :
27 :2008/02/28(木) 19:26:18
>>32 まいった。ありがとうございます。
無理やりmap<mutable cell,double >::iterator IT;
とか書いてみたけど無理っぽかったです。
他の手段か・・重ねてありがとう。
>>34 mutable使うならメンバーに
あまり好きではないけど
36 :
27 :2008/02/28(木) 19:35:30
>>33 pimplちょっと調べてみたんですが難しくて・・覚えておきます、ありがとう。
>>35 メンバー関数の先頭にはmutable付けられなかったです。
変更されることになるデータメンバの先頭につけてみたけど変わらず・・。
>>36 mutableデータメンバはconstメンバ関数から変更できる
>>36 mutableを非staticなメンバーに指定すれば、constメンバー関数内で
変更できるはずだけど。
pair の vector コンテナじゃ駄目ですか><
40 :
デフォルトの名無しさん :2008/02/28(木) 21:41:36
前レス >944 すいません。前回ポインタの格納場所について質問したものですが お礼を言うのを忘れていました。 ありがとうございます。
>>34 キーがconstなのは、キーでソートされるからであって、
mapに格納したまま書き換えたら順序を守れなくなる。
一旦mapから削除して、書き換え後に再度insertすべきでは?
42 :
sage :2008/02/28(木) 22:21:56
質問します。たったこれだけのコードが動きません。 ポインタのポインタを使ってみたのですが。教えてくだされ。 #include <stdio.h> #include <string.h> const char* string; const char** address; char str[1024]; void inputadd(const char* stradd){ address=&stradd; } void inputstr(void){ char teststr[]="abcdefghijklmn"; strcpy(str,teststr); *address=str; } void main(void){ string=NULL; inputadd(string); inputstr(); printf(string); }
>>42 address=&stradd; ←これがダメ
straddはinputadd内のローカル変数だ。
関数を抜けると無くなるので、addressはトンでもないところを指すことになる。
44 :
29 :2008/02/28(木) 22:30:58
自己解決しました(。。)゛ 分割コンパイルを行わないといけないのですね。 記述にばかり目を奪われておりましたが、 やっと問題点に気がつきました。 レスが無いのも納得がいきます。 それでは。
>>43 サンクス。ポインタは引数なら直でいけるという思い込みだったわ。
関数内で使っているものはポインタの値のコピーに過ぎないわけだな。
下みたいにして乗り切ったが正解でいいんだよな?
void inputadd(const char** stradd){
address=stradd;
}
46 :
デフォルトの名無しさん :2008/02/28(木) 22:39:56
初心者は、newやポインタを使わない方がいい STL使えばすべて片付く
使わなければいつまで経っても初心者だ。
練習コードなんだから、なんでもやってみればいい。
>>45 OK
48 :
デフォルトの名無しさん :2008/02/28(木) 23:03:04
上級者もnewやポインタを使わない方がいい 使うのは、速度やサイズの気になる場面だけだ それまで気になるならアセンブラにする
49 :
デフォルトの名無しさん :2008/02/28(木) 23:04:10
極論するとC言語は使わない方がいい
極論するとプログラミングなんかしない方がいい
速度が気になるんだったら、newを使うのはいけないと思うんだ。 少なくとも考えなしに使うのは。
boost::Pool
>>51 実測もせずに new を避けるのも良くない。
結局のところ重複はこっちでいいんかい?
>>53 は受け売りでしゃべっているだけですから気にしないでください。
newのなにがいけないのだろうか? 動的にオブジェクトの生成をしたらだめ?
馬鹿?馬鹿なの?ねえ? あえてだめっていう理由があるとしたらオーバーヘッドだろうか、ログ読んでないからなんともいえないが
58 :
27 :2008/02/29(金) 11:39:19
>>37 ,38,39,41
昨日は急用で落ちてしまいました27です。
>mutableを非staticなメンバーに指定すれば、constメンバー関数内で
変更できるはずだけど。
を実践したところコンパイル通りました!
constとかややこしくて触らないようにしてたんですけど
これからちょこっと勉強してみようと思います
みなさんありがとうございました!!
59 :
デフォルトの名無しさん :2008/02/29(金) 12:10:15
基本的に動的確保は頻繁にやるべきではない 不安定になる
>>59 動的確保が悪いんじゃない。正しく扱わないプログラマが悪いんだ。
C++ なら、 new したらすぐ auto_ptr なりに突っ込んどくとか、
new [] したくなったら標準コンテナを使うとか、そういう正しい対処をしとけば
ミスもほとんど防げる。
原因も把握せずに「不安定になる」とか言ってプログラムの手段を
制限するのは得策じゃないね。
61 :
デフォルトの名無しさん :2008/02/29(金) 12:24:44
あらかじめ必要な領域を見積もって確保すべき for(n=0;n<100000;n++) str+="A"; などは解放確保を繰り返し良くない
reserve 使っておけばいいし
本業はWEBアプリ屋なんですが、必要に迫られてActiveXの開発することになったC++ド素人です。 環境はVS2008、作ろうとしてるモノはMFC ActiveXです。 内部で文字列の暗号化処理(Blowfish)をしたいのですが、以下のソースを書いてコンパイルも 一応通ったものの、案の定うまく動きません。 LPSTR lpszPassword; //パスワード LPTSTR lpszInputStr;//暗号前文字列 //↑に値を適当にセットした上で↓ UCHAR digest[16]; MD5String(lpszPassword, digest); CBlowFish bf; bf.Initialize(digest, sizeof(digest)); unsigned char* outBuf = (unsigned char*)malloc(sizeof(lpszInputStr)); // エンコード bf.Encode((unsigned char*)lpszInputStr, outBuf, sizeof(lpszInputStr)); printf("%S", outBuf) よくわからなくて、ググりつつ適当に書いたソースなのでめちゃくちゃだと思います。 最終的には暗号化されたMD5ハッシュ値のような感じの文字列が出力されることを期待 していたのですが、バケバケな上入力値を変えても同じ値が返ってきますw 若干お手上げなので、皆さんのお知恵を拝借ください
64 :
63 :2008/02/29(金) 13:49:43
waveファイルを再生しようと思い、playsound()というAPIがあるよ、と教えて貰ったので 調べてみたのですが、 VC++2005 #include <mmsystem.h> // PlaySound()のため #pragma comment(lib,"winmm") #define FILENAME "Windows XP Startup.wav" LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { switch(uMsg){ case WM_DESTROY: PostQuitMessage(0); return 0; case WM_LBUTTONDOWN: //再生 PlaySound(FILENAME,NULL,SND_FILENAME | SND_ASYNC | SND_LOOP); return 0; case WM_RBUTTONDOWN: //停止 PlaySound(NULL,NULL,0); return 0; } return DefWindowProc(hWnd,uMsg,wParam,lParam); } このようなサンプルを見つけたのでコンパイルしてみたのですが、 error C2065: 'CALLBACK' : 定義されていない識別子です。 error C2065: 'DRIVERPROC' : 定義されていない識別子です。 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません なぜでしょうか?
>>65 #include <windows.h>
>>66 ありがとうございます。ですが、まだエラーが出てしまいます><
VC++2005
#include <windows.h>
#include <mmsystem.h> // PlaySound()のため
#pragma comment(lib,"winmm")
#define FILENAME "Windows XP Startup.wav"
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg){
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_LBUTTONDOWN: //再生
PlaySound(FILENAME,NULL,SND_FILENAME | SND_ASYNC | SND_LOOP);
return 0;
case WM_RBUTTONDOWN: //停止
PlaySound(NULL,NULL,0);
return 0;
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
error C2664: 'PlaySoundW' : 1 番目の引数を 'const char [23]' から 'LPCWSTR' に変換できません
#define FILENAME TEXT("Windows XP Startup.wav")
>>68 ありがとうございます。&重ね重ねすいません。まだ駄目みたいです。
error LNK2019: 未解決の外部シンボル _main が関数 ___tmainCRTStartup で参照されました。
fatal error LNK1120: 外部参照 1 が未解決です。
エラーメッセージでぐぐれ
71 :
デフォルトの名無しさん :2008/02/29(金) 14:33:42
#include <windows.h> #include <mmsystem.h> #pragma comment(lib,"winmm.lib") main(){ PlaySound("C:\\WINDOWS\\system32\\oobe\\images\\clickerx.wav", NULL,SND_FILENAME | SND_ASYNC | SND_LOOP); Sleep(2000); PlaySound(NULL,NULL,0);}
>>69 main関数がないのに動くわけないだろう
>>70 int main を追加する方法や システム>サブシステムをwindowにする方法
エントリポイントにMainを追加してみたりは試した上で質問はしました。。><
VCだよね?mainをこう書いてみたら? int APIENTRY _tWinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR lpCmd, int nCmd) { ... } あとWindowProcを呼ばせるにはちゃんとウィンドウを作って、 メッセージ処理しないとだめだと思うぞ。
>>72 書き終わった直後に気付いて書いてみたのですが根本的な原因は別にあるようでした。
>>74 そうみたいです!。ありがとうございます。
>>71 これに、文字セットをマルチバイトにしてみたところ。うまくいったので、これをベースにして、考えているプログラムにしてみたいと思います。
みなさんお付き合い頂いてありがとうございました。
>>63 >unsigned char* outBuf = (unsigned char*)malloc(sizeof(lpszInputStr));
俺unix屋だから windows のこと詳しくないけど
lpszInputStr は LPTSTR だからポインタだと思うよ。
上のコードのしていることは文字列の分ではなく
ポインタのサイズの分をmallocで確保している。多分4バイトくらい。
まず文字列のバイト数を正しく求めることから始めないといけないんじゃないかな。
size_t size_of_in = sizeof(TCHAR) * (lstrlen(lpszInputStr)+1); // NUL 文字に+1文字分
あと outBuf には暗号化されたバイナリが入るだろうから
printf("%S") ではうまく表示されないと思うよ。バイナリで扱わないと。
他にも暗号化単位やバイトオーダーなども問題になるかもしれないよ。
77 :
63 :2008/02/29(金) 16:02:41
>>76 ども、ありがとうございます。
PHPやASPな人間なもんで、厳密な型変換やったことないんでさっぱりです。
バイナリを文字列(1-9,a-z.A-Z)に戻すのは、どうすればいいんでしょうか。
newってそんなに遅いの?
その程度のオーバーヘッドも看過できないような状況では十分に「遅い」。
まぁ、何を作ってるか、によるよね。 趣味でLisp方言作ってたときは、operator new()を工夫しただけで全体の動作が3割速くなったし。
>>79 boost::Poolのほうが断然速かった。
>>78 メモリマネージャ次第じゃね?
Windowsに限ってもVCとBCBじゃnewでもメモリ確保の仕方違うし。
newを忌避しすぎるのも意味が無い。「まだ最適化するな」。
84 :
デフォルトの名無しさん :2008/03/01(土) 01:01:15
初期化方法おしえてください 全部通りません vector<int> x={1,2,3}; vector<int> x(3,{1,2,3}); vector<int> x({1,2,3});
>>84 static int const initial_x = {1,2,3};
vector<int> x(&initial_x[0], &initial_x[3]);
86 :
85 :2008/03/01(土) 01:05:36
ごめん。 [] が抜けてた。 static int const initial_x[] = {1,2,3};
87 :
デフォルトの名無しさん :2008/03/01(土) 01:08:49
そういうやり方しかないですか・・・そしたらint x[]={1,2,3}ですませます すみません
#include <boost/assign/std/vector.hpp> ... vector<int> v; v += 3, 1, 4;
boost::assignとか
90 :
89 :2008/03/01(土) 01:16:55
ごめんリロードしてなかった
91 :
デフォルトの名無しさん :2008/03/01(土) 01:21:24
vectorに関数追加する方法ありませんか? x={1,2,3}の代入を可能にする関数です
配列数が8000ぐらいあるものでそれぞれが4つくらいのアイテムを持っている場合、 vectorやらmapやらを使いたいんですが、メモリ消費や処理速度的にどのようにしたらよいでしょうか? ちなみに8000くらいあるほうは歯抜けで番号が記録されていてコール元から頻繁にアイテムを求めてきます。(ユニークキー) 4つくらいのアイテムの方は可変になってしまうのでそれぞれをvectorにしようかと思ったのですが、 消費メモリが大きくなりそうだったので悩んでいます。
ありません
>>92 「なりそう」で悩む前に素直に実装してみて、実際のメモリ消費量見てから考えるのがいいよ。
96 :
デフォルトの名無しさん :2008/03/01(土) 01:44:11
vec x(10, 10, 10, 0); で初期値0の3次配列を定義できるようにするには、どう書けばいいですか? int 型限定でよいです 4次や5次もしたいです
>91 無理。C++0x を待て。
>>95 ありがとうございます。
ちょっと試してみます。
業務で初めてC++使っているので勉強の毎日です。><
100 :
デフォルトの名無しさん :2008/03/01(土) 01:56:57
このように書けば可変個の引数をとれますが、内部の型が一つに決まってしまって変更できません どうすればいいですか? class vec{ int x; public: vec(int n, ...){} };
template使え
102 :
デフォルトの名無しさん :2008/03/01(土) 02:04:43
100次元でもできるようにするためには、テンプレートを再帰的につかうようにすれば いいと思いますがわかりません どう書けばいいですか
まだこれいたのか
もう誰も触るなよ。
Cのcursesについてお教ください printw("mojiretsu"); char buf[]="mojiretsu" printw("%s",buf); これで前者が表示され後者が表示されないのは何故なんでしょうか。
>>105 環境くらい書いた方が。
どちらのコードも問題はないと思う。
refreshはしている?
前者が表示されているってことなので大丈夫だとは思うけど。
お試しコードみたいに短いのを書いていて、
printw→refreshのあと、すぐにendwinとかしてたら表示が見えていない可能性あり。
107 :
105 :2008/03/01(土) 04:36:50
OSはクノーピクスのDVD最新ver、コンパイラはgccです。 int main() { initscr(); move(5,1); printw("mojiretsu"); refresh(); char buf[]="mojiretsu"; move(8,1); printw("%s",buf); refresh(); getch(); getchで止まった時に上のmojiretsuは表示されているのに下はされないという状態です。 最初はcygwinでやろうかと頑張ったのですが、cursesライブラリがどうやってもリンクできずクノーピクスを使うに至っています。
>>107 fedoracoreでは特に問題なく二つの行ともに表示された。
そのソースでcursesを使うプログラムとしては特に問題はないと思うけど、
くのーぴくすに入ってるライブラリのバグなのかな……
windows上でなら、cygwinのcursesでもいいと思うけど、
PDcursesを取ってきて自前でライブラリを自分の得意の環境でコンパイルする手もあるよ。
それならリンクのやりかたが分からないとかって問題もないと思う。
printw("mojiretsu");とprintw("%s",buf);の順番が逆の時はどう?
110 :
105 :2008/03/01(土) 05:57:14
逆にした場合もprintw("mojiretsu");の側しか表示されません。 どうやら環境が問題のようなので108さんが紹介してくださった方法等試してみます。 ありがとうございました。
printwww
112 :
デフォルトの名無しさん :2008/03/01(土) 09:03:27
C++のdeleteについて質問させてください。 環境はWindowsXP VS2005EEです。 newしたポインタをdeleteすると、メモリの中身がfe ee fe eeとなります。 fe ee fe eeという値には何か意味があるのでしょうか?
>>112 メモリ管理の都合やらデバッグの都合やらで値を書き換えているのかも
しれない。ともかく、delete後のメモリなんて参照しちゃダメ。ぜった
いダメ。
>>113 もちろん、その値を何かに使ったりはしませんが
見るだけでも何かまずいことがおこるんですか?
ネットからダウンロードしたデータがシフトJISコードの場合char型のに入れると 文字化けしてしまってまともに処理できないんですが、ecuに変換すればいいんでしょうか? できたらやり方かサンプルソース公開してくれてるサイト教えて欲しいです
間違えたecuじゃなくてEUC
>>117 ありがとう。勘違いしてたEUC→SJISに変換だった
自力で関数作ってどうにかできました
>>114 起こらないかもしれないが、起こるかもしれない
まだOSにメモリを返してなければ大丈夫かもしれないが、
返しちゃってた場合はアクセス違反で落ちるかも
処理系の実装と運次第
>>114 動作未定義だから鼻から悪魔が出るかもしれんし、HDDが
フォーマットされるかもしれない。
VCで定数のアライメントってどうするん? packじゃ出来なかったYO
定数のアライメント に一致する日本語のページ 約 件中 - 件目 ( 0.201466 秒) 定数のアライメント に該当するページは見つかりませんでした。
ifとswitchくらいしかまだ使ったことがないのですが、 条件分岐をする際 if を良く使います。ifの中にifその中にif って普通でしょうか?
普通
あまり深くすると後で読みづらくなったりする。個人的には5段とか行くと分割を考える。
126 :
デフォルトの名無しさん :2008/03/01(土) 18:14:46
C++で、doubleという名前の関数を作れるでしょうか? void double(int a); とかそんな感じ。今あるソースをみているんですが、コンパイルできなくて、 どうもそこでひっかかってるんじゃないかと。。できないとおもうんですが、 そう言いきってしまっていいですか?
doubleは予約語だから当然ダメ。Doubleならおk
128 :
デフォルトの名無しさん :2008/03/01(土) 18:32:13
129 :
デフォルトの名無しさん :2008/03/01(土) 18:49:02
コンパイラや標準ライブラリベンダが使用する識別子について質問です どうやら以下の条件を満たす識別子は使ってはいけないみたいですが 1 _で始まり、大文字が続く名前 2 __(アンダースコア2こ)を含む名前 3 グローバルスコープで _で始まる名前 ケースA int _Hoge;//ダメ(1に抵触) ケースB int __hoge;//ダメ(2,3に抵触) ケースC int hoge__hige;//ダメ(2に抵触) ケースD int _hoge;//ダメ(3に抵触) ケースE namespace foo{ _hoge;} //これはok? ケースF class Hage{ int _hoge;} //これはok? ケースEとFが合法なのかどうかわかりません この辺を指摘(警告とか)してくれるコンパイラとかないんですかね
ないでしょうね、なにろ標準ライブラリが使っているわけですから・・・ しかし、初めてみたなそのルール。 _ __ が最初につく名前は駄目だというのは知ってたけど。 129 ルールでは E F は合法っぽいけどね自分の知っているルールでは非合法だ。
>>129 _ に小文字が続く識別子に関しては、
グローバルネームスペースでのみしか禁止されていない。
でも、マクロでは禁止されてた気がする。
マクロはnamespace関係ないからな。
133 :
デフォルトの名無しさん :2008/03/01(土) 19:44:45
__FILE__や__LINE__ってどのファイルに定義してあるのでしょうか??
大抵は字句解析器が置換する。
tryブロックでthrowされた例外がcatchされてcatch内で例外処理が成された後、 正常系はどこから復帰になるのでしょうか?
最後のcatch節の下
復帰しないよ?そのまま続く。 try{ A; //例外発生 B; }catch( exception &e ){ C; //例外処理 } D; なら、正常は:A, B, D。 Aで例外時は:A, C, D。 もちろん、Cで例外が発生したり、throwしたりしたら別だけど。
138 :
デフォルトの名無しさん :2008/03/01(土) 19:58:13
Win32APIのWindowsアプリケーション開発環境を作るためにPlatform SDKを インストールしたのですが、corewin_express.vspropsのデータの修正が出来 なくて困っています。 どうしたら、修正する事が出来るようになるのでしょうか? ちなみに、OSはvistです。
139 :
デフォルトの名無しさん :2008/03/01(土) 20:01:49
visual stdio2008のexpressいれとけ
140 :
デフォルトの名無しさん :2008/03/01(土) 20:13:48
>>136-137 ありがとうございます
tryブロックの範囲の選定も気をつけないといけないようですね
またまた質問なんですが
std::exceptionを継承してMyExceptionクラスを作ってそこに、例外発生時のログ取り機能を追加しました
不正な引数を取ってしまったときinvalid_argumentのような例外クラスを投げたいのですが
多重継承は色々ややこしいのでMyExceptionから派生させて相当の自作クラスを投げる
やっぱりMyExceptionとinvalid_argumentの多重継承を行う
どちらがよいのでしょうか?
ログ取り機能を例外クラスから分離した方がいいと思う。
MyExceptionからログ鳥部分を分離して、派生のない ExceptionLogクラスを作り、std::invalid_argumentと 派生した例外を投げる、みたいな。
>>142-143 必要な標準例外クラスから派生したmy標準例外クラスを作って
そのクラスにログ取り機能クラスを保有させたほうがいい
ということですよね?
そのほうが系統だった例外クラスの構造になるのでしょうか?
145 :
138 :2008/03/01(土) 22:11:41
2005で作りたいのですが、いい方法はありませんか? どこかの設定をいじると書き込み可能になったりとかないんでしょうか・・・。
146 :
デフォルトの名無しさん :2008/03/01(土) 22:12:05
1クラスに2つ以上の機能を入れるのは一般によくないとされている
とりあえずロガークラスを作るのは確定としても、 以降をどう実装するかは結構悩みどころだな。 個人的には throw をマクロ LOG_THROW みたいなので置き換えて、 その中で例外を投げる前にログを取るようにするのがいいと思う。 マクロは使わずに済むなら使わないのが一番いいんだけど、 デバッグ時に __FILE__, __LINE__ を利用したり、 文字列化演算子を使って移植性の高い方法でクラス名を表示したりできるから、 ログ取りには便利だと思う。
質問です。 ヘッダをインクルードせずに class Cls* pCls; と書くのはOKなんですけど namespaceで括られた場合に class Name::Cls* pCls; と書くと'Namne' : 識別子がクラス名でも名前空間名でもありません。 とエラーが出ます。 インクルードせずに宣言する方法ってあります?
>>148 こうかな
namespace Name{
class Cls;
}
Name::Cls *pCls;
ところで標準例外std::exceptionの中身ってどうなってるんだろう?
151 :
デフォルトの名無しさん :2008/03/02(日) 00:12:35
CLASS x={1,2,3,4,5,6}; はどのようにかけばジツゲンできますでしょうか
boost::arrayでも見れば?
>>152 要するにあれは構造体の初期化だよね。
コンストラクタが無ければクラスだろうが
あのタイプの初期化ができることを利用しているという。
boost::arrayは {{ }} で囲わないとダメだろう。
156 :
148 :2008/03/02(日) 00:49:28
>>149 無事宣言することが出来ました。
ありがとうございます。
お礼にオプーナを買う権利をあげます。
「↓」を表示後、キー入力があるまで処理を一時停止させ、 キー入力があればそれに対応した動きをさせたいのですがどうすれば良いでしょうか? getch()だと入力待ちカーソルが邪魔になってしまい、困ってます
159 :
デフォルトの名無しさん :2008/03/02(日) 01:13:39
>>157 別スレで環境依存だといわれたろ?
なぜ環境を書かない
160 :
157 :2008/03/02(日) 01:17:19
すみません、vidual studio2005のC++です
>>147 実装方法ですか。
マクロを使うというとこういう感じになるのでしょうか?
ErrorLogger(char* filename, int linenumber, const char* errmsg)
のようなロガークラスを用意して、
コンストラクタ内でエラー内容を記録させてしまうようにしておいて
#define THROW(msg , exception_type) ErrorLogger log(__FILE__ , __LINE__ , msg);\
throw exeption_type\
というようなマクロを組めばよいのでしょうか?
というか、初めてマクロを組んだのであってるかどうかも判りませんorz
>>161 自己レスながらマクロ修正してみた
#define THROW(msg , exception_type) ErrorLogger log(__FILE__ , __LINE__ , msg); \
exception_type e;\
throw e\
これでだいじょうぶですかね?
>>161-162 ErrorLogger をクラスにする意味がわからない。関数でいいだろ。
例外オブジェクトにデフォルトコンストラクタしか使えないのは無駄な制限。
マクロ名は動作を表すように LOG_AND_THROW() とかにしたほうがよくない?
あと、最後の \ が余計。
inline関数でいいじゃまいか。何故define・・・しかもTHROWはないなw
>>164 __FILE__, __LINE__ は inline 関数だとマズイだろ。
#define LOG_THROW(type) \ do { \ :LogAndThrow(#type, __FILE__, __LINE__); \ throw type(); \ } while(false) void LogAndThrow
途中で送ってしまった・・・。
#ifdef NDEBUG #define LOG_THROW(type) \ do { \ LogAndThrow(#type); \ throw type(); \ } while(false) void LogAndThrow(const char* type_name) { ErrorLogger log; // ここでログをとる } #else #define LOG_THROW(type) \ do { \ LogAndThrow(#type, __FILE__, __LINE__); \ throw type(); \ } while(false) void LogAndThrow(const char* type_name, const char* file_name, int line) { ErrorLogger log; // ここでログをとる } #endif こんな感じ。 実際には関数の実装は .cpp 側に書くわけだけど。 THROW という名前は何かと使われている恐れがあるので止めた方がいい。 LOG_THROW って名前も、実際には何か接頭辞を付けた方がいいと思う。
しまった。ログとるだけにしたから LogAndThrow じゃなくて LogError だな。
もちつけ
171 :
デフォルトの名無しさん :2008/03/02(日) 13:09:31
ifstreamで読込みをしているとき、改行を読み込んだことを知るにはどうすればよいですか?
読み込んだ内容が改行を含むかどうかチェック。 1行ずつ読み込みたければ getline が使える。
173 :
デフォルトの名無しさん :2008/03/02(日) 13:16:15
>>172 int a;
ifs >> a;
みたいにやってるんですが、
> 読み込んだ内容が改行を含むかどうかチェック。
はどうやればいいですか
ああ、そういうことか・・・。 それは無理じゃないかな。
175 :
デフォルトの名無しさん :2008/03/02(日) 13:20:54
>>174 じゃあ、一行ずつ読みたいなら、getline()でやるしかないですか?
176 :
デフォルトの名無しさん :2008/03/02(日) 13:25:32
以下のようなとき、 子クラスのオブジェクトから、func(1)を実行すると、 func(const char* ch)を呼んでしまうのですが、 親クラスのfunc(int i)を呼ぶにはどうすればいいのでしょうか? /*****こんな感じ*****/ class Parent{ public: void func(int i); }; class Child : public Parent{ public: void func(const char* ch); }; /*******************/
>>175 そうなる。
getline した後 istringstream に渡してやるとか。
>>176 Child ch;
ch.Parent::func(1);
>176 子クラス Child の func() によって親クラス Parent の func() が隠蔽されている。普通にオーバーロードしたいなら class Child : public Parent { public: using Parent::func; void func(const char* ch); }; とすることで Parent での func() も見えるようになる。
180 :
176 :2008/03/02(日) 14:07:51
namespace temp { class Test { private: std::ostringstream oss; public : ~Test() {std::cout << oss.str();} template <typename T> friend Test &operator <<(Test &, T t); }; } template<typename T> temp::Test &operator<< (temp::Test& test, T t) { test.oss << t; return test; } を、temp::Test() << 2; と使うと、「operator << が曖昧です」というコンパイルエラーになります。 名前空間を使わないとコンパイルできるのですが、何が問題なのでしょうか Win2k、VC2005です
<< の実装部も temp 名前空間に入れないと。 temp::Test 内で宣言してる friend 関数は temp 名前空間内に入る。 だから、今は temp::operator<< と operator<< の2つがある状態。
あるいは friend のところを ::operator<< にするかだけど、 temp 名前空間内に入れた方がいいと思う。
コマンド等文字列処理で2重のループから抜けるときに goto文使うのって邪道かな? いつも使ってるんだが。
2重ループから抜ける際に goto を使うのは常套手段
俺、今まで一度も使ったことが無い。 使いたい衝動に駆られたことはある。
小さい関数内なら結構goto使っちゃうなぁ
常套手段ではあるけど、 2重ループから抜ける必要があること自体があまりないよね。
まあ関数は一目でざっと目通せる程度にするもんだしちゃんと考えて使うならぜんぜんいいと思う
191 :
デフォルトの名無しさん :2008/03/02(日) 15:36:50
ポインタを解放した後、安全のためNULLを入れると書いてたんですが、 NULLを入れると何が安全なのでしょうか?
解放されているかどうかを NULL チェックで確認できる。
二重にdeleteすることが無くなる(delete(NULL)は安全なことが保障されている)
NULL なら間違って解放後にアクセスした際にエラーになってくれる環境が多い。 NULL じゃない場合は偶然アクセスできるかもしれないが、 メモリ領域を壊したり変な値を取得したりしてしまう。
無限ループでポインタインクリメントでもしながら片っ端から表示してみれば良いわけない
196 :
デフォルトの名無しさん :2008/03/02(日) 15:49:10
すみません keybd_eventみたいに プログラムからキーボードを押したことにするのは gccだと何か方法がありますか・・・?
>196 keybd_event は Windows API。gcc はいろんな環境向けがあるコンパイラ。 例えば Windows 上で gcc を使っているなら keybd_event になるわけだしやりたいことをもっと正確に書こう。
初心者です。 デフォルトコンストラクタっていうのは、 1.引数なしで呼ばれるコンストラクタ 2.なにも記述してなくてもデフォルトで呼ばれるコンストラクタ のいったいどっちのことなのですか? 1と2の違いは、例えば、引数なしのコンストラクタを 自分で定義したときに、それをデフォルトコンストラクタと いうかどうかという違いになると思うのですが、、、 1と2の説明ともWEB上で見かけますが、 どちらがより正確なのでしょうか?
引数無しで呼ばれるコンストラクタ。 自分で定義しようがデフォルトコンストラクタ。
>>198 引数なしで呼ばれるというよりは引数なしで呼ぶことが可能なと
いったほうがいいかもな。デフォルト引数もあるから。
class Widget {
public:
Widget(int i = 0) {}
};
//例えば
Widget w; //このsyntaxがデフォルトコンストラクタを要求する。
//Widget::Widget(0)が呼ばれる。
201 :
198 :2008/03/02(日) 17:35:37
>>199 ありがとうございます。
すっきりしました。
202 :
198 :2008/03/02(日) 17:37:25
>>200 おっと行き違いになりました。
そうですか、
それもデフォルトコンストラクタなんですね。
ありがとうございました。
203 :
196 :2008/03/02(日) 18:15:40
>197 すみませんでした OSはDebianでPDFかパワポのようなものを C言語で操作したいのです 具体的には下キーかEnterキーをC言語で押したことにして スライドを進めることを行いたいです
204 :
191 :2008/03/02(日) 19:36:37
205 :
デフォルトの名無しさん :2008/03/02(日) 21:56:29
>>205 C言語の個人講習をして欲しい訳だな?しかも無料で!
そんな奇特な人は少ないが候補として
C言語を覚えたてで自分のために他人に説明する人がいるが
そんな人を探すくらいなら良書を買ったほうがいくぶんかマシ
C言語をマスターしていながら教えてくれる人がいるとしたら
リタイヤした人くらいだろうな
207 :
デフォルトの名無しさん :2008/03/02(日) 22:08:50
string tmp; cin >> tmp; としたとき、改行だけが押されたことを知るにはどうすればいいですか?
>>207 フォーマット入力はデフォルトでは空白類記号は読み込まれない。
gcc をつかった 分割コンパイルの仕方がわからないのですが わかりやすく解説したページはないでしょうか?
gcc -c hoge1.c gcc -c hoge2.c gcc -c hoge3.c gcc -c hoge4.c gcc -o hoge hoge1.o hoge2.o hoge3.o hoge4.o
>>209 Makefileでググれば、良いと思う。
namespace Name { class Cls; }
丸一日前のレスにレスか
Makefileとbjamとどっちがいい? やっぱ標準であるmakeは一通りやっとくべきかな?
215 :
デフォルトの名無しさん :2008/03/03(月) 01:14:07
>>208 ありがとうございます。一応自分で書いてみましたが、まだうまく動きません。
noskipwsをした後、おかしくなります。
どうかよろしくお願いします。
std::string filename = "default_file.txt";
while (1) {
std::string tmp;
cout << "Input file name : (hit return to default: " << filename << ") ";
cin >> std::noskipws >> tmp; // 下の(1)でY以外で答えたとき、ここで入力を受け付けてくれない。
if (tmp.empty()) {
// リターンキーだけが押された場合に、ここのIF文に入る
tmp = filename;
}
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cin >> std::skipws;
cout << "filename : " << tmp << " OK (Y|N) ? ";
std::string ans;
cin >> ans; // (1)
if (ans == "Y") {
filename = tmp;
break;
}
}
216 :
デフォルトの名無しさん :2008/03/03(月) 02:22:41
stdlib.hの中で_CRT_DOUBLE_DECと_LDSUPPORTを定義してないとき_CRT_DOUBLE、_CRT_FLOATといった構造体を用意してるようですが、 _CRT_DOUBLE_DECと_LDSUPPORTとこの2つに囲まれた構造体などは何のために用意してるんですか?
>>215 改行は読み込まないからgetlineがいい。
std::string filename = "default_file.txt";
while (1) {
std::string tmp;
std::cout << "Input file name : (hit return to default: " << filename << ") ";
std::getline(std::cin, tmp);
if (tmp.empty()) {
tmp = filename;
}
std::cout << "filename : " << tmp << " OK (Y|N) ? ";
std::string ans;
std::getline(std::cin, ans);
if (ans == "Y") {
filename = tmp;
break;
}
}
C++ってどういう業界の人がつかってるの? GUIでMFCやVCL、Qtさわるくらいはあるが、 ゲーム以外でフルスクラッチで書き上げる人たちって どういう人?
趣味
やっぱそうか。 抽象化なんて考えてる暇あったら別の仕事が 飛んでくるもんね。
最近C#なんか使う企業もねえ
つまりCωの時代がやってくると。
時代はwebアプリか・・・
業務ソフトなら実際C#とか.NETでもなんら問題なくなってきてるご時世だもの
225 :
デフォルトの名無しさん :2008/03/03(月) 03:59:03
俺は金融関係だけど、C++使ってるよ。 matlabを使うとこも多いけど。
自動車関係企業のシステム部門ってC/C++使うのかなぁ
いかにも使いそうじゃないか
229 :
デフォルトの名無しさん :2008/03/03(月) 04:51:56
昨日から色々質問させてもらっているものです。 色々分かってきたのですが、getlineとcinとの併用のときにどう書くべきかわかりません。 #include <iostream> using namespace std; int main() { int a; string s; cout << "int: "; cin >> a; // cin.ignore(numeric_limits<streamsize>::max(), '\n'); cout << "string: "; getline(cin, s); cout << "int: "; cin >> a; return 0; } 上記のソースでコメントアウトしている箇所がありますが、コメントアウトしたままだと、 真ん中のstringの入力が、1つめのintの入力の改行を拾ってしまうせいで、とばされてしまいます。 そこで質問なのですが、ここにコメントアウトされている行をいれるのは正しいですか?
>>229 コメントアウトした行を入れてもだめ。
cin >> a; で改行文字がバッファに残るため、それが次のgetlineで
読み取られてしまう。Cで言う所のscanf()とgets()を混在させた問題と同じ。
解決策はgetline(cin, s); をもう一つ付け足して改行文字を読み飛ばす。
もしくはgetline()に統一する。
今の所COBOL、PL/I、Java、JS、Access、Rubyを見たことがある
>>225 金融っていってもmatlab使ってるようなところは
複雑な数値計算やってるだろうからちょっと特殊だな。
車でもカーナビのように限られたリソースでGUI作るようなところは
使ってるだろうが、間違っても制御には使わんと思うんだが。
233 :
デフォルトの名無しさん :2008/03/03(月) 05:53:38
>>230 ありがとうございます。
getline()とcinを混在させないのが一番いいと。でも、cinが便利なので、
基本的にはcinを使いつつ、cinだと改行を扱うのが不便なのでその時だけgetline()を
使う、という風になりそうです。(自分としては)
すると、
(1)getline()する前にバッファに改行が残っているか確認して、残っていれば消す。
(2)cinした後には改行を消しておく。
のどっちかになると思うのですが、今回は(1)の方法が分からなかったので、(2)で実装しました。
どっちにしても、cin関係はなんか使いにくい感じ。
linux のmmapのこと調べてて疑問に思ったので質問。 mmap でファイルを仮想メモリにマッピングしたとき、OSがファイル上のデータを ブロック転送する、アプリがその領域に書き込むとOSがファイルにそれを反映すると 書いてあった。 mmapでマップされた領域に上のあるアドレスに代入したとき、 OSは代入されたことを知っているの? 代入演算子で値を放り込むことと、read write のシステムコールを使うのは 根本的に違いますよね?
>>234 C/C++の問題じゃないと思う
多分OSがマッピングした領域は書き込み不可の属性が付いており
書き込んだらCPUに割り込みがかかってそれを利用してファイルに反映してるか
そんな所だと思う
>>236 失礼しました。
環境に依存する内容は避けたほうがよいですね。
>>237 環境依存OKのスレだから問題ないんだけどC/C++よりも
linuxの話になるね
ちなみにWindowsの仮想メモリとメモリマップトファイルも似たような
機構で実現している
複数ある単語から文字列中最初にマッチする物を探す用途で、 こんなのを考えてみたのですが、こういう2分木辞書ってなんて 名前になるんでしょうか? サフィックスツリー?(これよりもっと複雑なようですが) typedef std::map<char, Node> Tree; //char に単語の1文字が入る struct Node { Node *pChild; //次の文字ノード int No; //登録番号、兼、非末端(-1) } 単語がab,ba,ac,abcとあるなら、子ノードの繋がりが下記のようになる。 先頭 <a,-1> <b,-1> / \ / <b,0> <c,3> <a,1> / <c,3>
訂正 struct Node { Tree *pChild; int No; }
&ClassName::memberVarName; って演算はいったい何を行っているのでしょうか? 最初オフセット値を得ているのかと思ったんですが、ためしに出力しても、1が出力 されるだけです。 元ソースでは、これを引数にしてメンバ変数のオフセット値を得ているようですが…
>>242 ありがとうございます。おかげで理解できました。
メンバポインタからオフセット値を得るには、
&( static_cast<A*>(0)->*memPtr )
で仕様上問題ないでしょうか?
単にオフセットが欲しいんなら offsetof を使えばいい
>>243 実際には動くだろうけど、仕様上は良くないような
ちゃんとインスタンスを用意した方がいいんじゃない
>>243 オフセットは POD 型に対しての offsetof でしか取れないよ。
素直にメンバポインタ通して参照しちゃダメなの?
>>229 仕様上正しい。
以下はJosuttis本の記述の要約。
istream& istream::ignore(streamsize count, int delim)
This form ignores up to count characters until delim is extracted and discarded.
(ストリームから改行まで抽出されて捨てられる。)
ちなみにg++ 4.0では無問題だった。
>>236 割り込みなんかかからない。
ページング機構を備えるどんなプロセッサでも(俺の知る限り)
プロセッサ自体に、書き込まれたかどうかのフラグ
(いわゆる、dirty bit と呼ばれるもの)をセットする機構がある。
例えばx86ならば、ページテーブルの該当ページを示すエントリ内にこれがある。
で、ファイルから読み込んだときにOSがこのフラグをリセットしておき
OSは、ページが不要になった時やsync要求が来たときにこのフラグを確認して
書き戻すか破棄するかを決定する。
>>248 それみたいですね。
すっきりしました、感謝。
>>245 ,246
仕様上ダメですか…違う方法を模索することにします。
>>249 すみません。
read write のようなシステムコールを実行するとOSデバイスドライバが
あとは処理してくれますよね?
代入演算子を使ってmmapした領域に書き込むとき、
そのフラグもセットするようにgccが実行ファイルを生成してくれるのでしょうか?
でもそれだと操作するアドレスがどこなのかをプログラムソースには書かなくても実行ファイルの中では
毎回見ているということでよろしいのでしょうか?
dirty bitを立てるのは249に書いてあるとおりCPUの仕事。 特にコンパイラがすることはない。
仮想記憶でぐぐればいいと思うよ。
ちなみに、少し前のLinuxカーネルのバグは この複数からの同一ページへのアクセス時に このフラグをうまく処理しなかったかららしい。 また、少し違うが phenomのバグはキャッシュに対するdirty bitの反映が 高負荷時に滞るというものらしい。
もう少し補足すると、 普通のページング可能なプロセッサは、 TLBと呼ばれる、ページテーブルのキャッシュを内部に持っている。 (x86以外では呼び方が違うかもしれない) したがって、該当ページへの書き込みがある度に 毎回物理メモリ上のページテーブルに書き込んだりはしない。 (TLB内の情報と変更があった場合のみ、書き込む) で、このTLBの内容を書き戻すときにまずキャッシュに書き込むわけだけど これがうまくいかない場合がある、というのがphenomのバグらしい。 L1とL2の関係もあるとかどっかで読んだが詳しくは覚えてない。
257 :
デフォルトの名無しさん :2008/03/03(月) 22:37:05
enumってプリプロセッサが解釈するのでしょうか??
いいえ。コンパイラたんがせっせこお仕事します。
>>253 ありがとう。
CPUのやるとことまで押さえるのは難しいな。
もちろん仮想記憶で調べたりもしてるんですが、
なかなか自分の知りたいところのたどり着けない。
使い方はソースも含めて載ってたりするんだが。
ちょっとお聞きしたいのですが stringクラスの関数でcompareというのがありますが、参考書によると int compare(const string& str) const; のように定義されているとあります。 この定義のconst string& の&ってどういう意味の&なんでしょうか? 最後のconstも、なぜここにconstがあるのか分かりません。 また、上の定義が宣言されている場所を探してみたのですが、そもそもそれが見つかりません。string.hの中にはないのでしょうか?? 質問ばかりで申し訳ないのですが、どなたか教えていただけると幸いです。
>>262 C++をもちっと勉強するといいよん。
&は参照。C++で導入された機能。参照についてはぐぐるよろし。
constは簡単に言うと「この関数はメンバ変数を変更しません」って宣言。
compare関数を呼ぶことで元の文字列を弄られちゃ話にならんだろ?
たぶん、これからも山ほど疑問が出てくるだろうから 入門書を読んだほうが早いと思う。
あと定義はstring.hではなくてstringの中だ。 string.hはCのヘッダーだからそりゃないだろうね。
>>262 > ちょっとお聞きしたいのですが
> stringクラスの関数でcompareというのがありますが、参考書によると
>
> int compare(const string& str) const;
>
> のように定義されているとあります。
> この定義のconst string& の&ってどういう意味の&なんでしょうか?
> 最後のconstも、なぜここにconstがあるのか分かりません。
>
> また、上の定義が宣言されている場所を探してみたのですが、そもそもそれが見つかりません。string.hの中にはないのでしょうか??
> 質問ばかりで申し訳ないのですが、どなたか教えていただけると幸いです。
例えばcompare(const string str)だとすると引数にstd::string型のオブジェを入れると
std::stringのコピーコンストラクタがstrに働いて無駄なメモリ間のコピーが働く
compare(const string& str) とする理由は引数に参照を取る事となり
コピーが働かないので無駄なメモリの消費がなくなる。
最後のconstはメンバ関数を呼び出したオブジェクトを修正できないようにすることです
267 :
252 :2008/03/04(火) 01:45:56
レスくださった方々ありがとうございます。 >std::stringのコピーコンストラクタがstrに働いて無駄なメモリ間のコピーが働く >compare(const string& str) とする理由は引数に参照を取る事となり >コピーが働かないので無駄なメモリの消費がなくなる。 なるほど!勉強になります。 あと、compareの宣言ですが、stringやcstringの中も見てみたのですが、みつからないんです。
>>267 更にstringからインクルードしている先にあるんじゃないか?
例えばcygwinのgccだと/lib/gcc/i686-cygwin/3.4.4/include/c++/bits/basic_string.hにある。
269 :
デフォルトの名無しさん :2008/03/04(火) 02:19:09
>>262 VSならソースコード中に#include <string>として
stringの所にカーソルあわせて右クリックでstringを開くを選択すれば
中身は見れるよ
適当なcompareのとこで右クリック→定義を参照すれば、basic_string::compare()かなにか出ると思うよ
あ、VSの話ね
たまにはBCBとかのことも思い出してね
grepくらい使えよ(´・ω・`)
findも使えよと混ぜ返したらDOSのfind.exeと誤解される罠。
プリプロセッサだけ通したモノにエディタで検索かけるのはダメですか…?
vector型で vector<int> num; num[i*j]=a; 見たいなことしたいのですが どうやるのでしょうか
templateで、特定の型以外が渡された場合にエラーなり 分岐なりする方法ってあるんでしょうか? たとえば template<class T> class Hoge { void Fuga(T &ref) { //ここで渡された型を知りたい }; } C++だと無理?
クラスAからそれぞれ派生したクラスB系統とクラスC系統のクラスがあるのですが Aのポインタ*pがどちらの系統か判別する方法はありますか? RTTIだとpの中身は分かるけどどういう系統までは追えないようですが良い方法はありますか?
意味が良くわからんかったけどメンバに識別子でもいれればいいんじゃない
>>279 デコレータパターンのConcreteComponentの型を判別する方法はないかな、ということです
>>278 dynamic_castはダウンキャストに失敗すると0を返す。
>>276 operator[](size_type)があるやん
>>284 そうなんですけど
出来れば再帰的に
DecoratorA-DecoratorB-DecoratorC-ConcreteComponent
と順番に型情報をたどって行く必要ができてしまって・・・
最悪でも、根元の情報だけでも何とかならないかと
>>285 なんですかそれ
>>287 Decoratorの方はいくらでもいじれるのですが
ConcreateComponentの方はこちらの一存ではいじれないので識別子を埋め込むのは難しいかと
やはりcastの成否で判別していくのが無難か・・・
castに失敗するとNULLが返る?
bad_castがthrowされるのは参照のキャストの時だっけ・・・
>>288 普通にnum[i * j] = aとすればいいということ。勿論、num.size()がi * jより大きいことが条件になるけど。
>>277 テンプレートで先ず全ての型で失敗するコードを書いておいて、
特別な型だけ特殊化しておくとか。
全く関係ないが キャストとくにdynamic_castを使用する度に クラス設計に問題があったんじゃないかと不安な気分になるのは自分だけか?
俺なんか気づいたら継承が全部public、メンバもほとんどpublicだったことがあるぜ! (´・ω・`)
でもcast使わざるをえない時ってあるから嫌らしいよな
>>280 ,291
すみません、説明がたりませんでした。
templateでtemplate型を受け取った時にも対応できる方法が
あるかが知りたかったんです。
例えばtempate関数でstd::vector<何でもOK>は受け取れるが
std::list<>はだめな場合など。
こういう場合、特殊化だとvector<int>、vector<float>〜という具合に
OKにしたい型を全て記述しないとダメなんじゃないですか?
297 :
291 :2008/03/04(火) 11:45:15
>>296 「特定の(少数の)型」だけ有効にしたいのかと思ったから特殊化を提示した。
そうでないんだったらtypeidで動的に型を調べることになるのかな?
templateスレ辺りの方が喰い付きがいいかも知らん。
>>296 こんなの?
#include <vector>
template<typename T> void foo(T const& x);
template<typename E> void foo(std::vector<E> const& x) {}
int main()
{
std::vector<int> vi;
std::vector<float> vf;
foo(vi);
foo(vf);
return 0;
}
concept check
301 :
267 :2008/03/04(火) 13:06:56
grepは使ったのですが、なぜかうまく検索できなかったので困ってました。 Eclipse CDT 使ってるんですが同じようなことができました。 ありがとうございました。
302 :
267 :2008/03/04(火) 13:07:28
grepは使ったのですが、なぜかうまく検索できなかったので困ってました。 Eclipse CDT 使ってるんですが同じようなことができました。 ありがとうございました。
[゚Д゚] castトキイテラグオルカラキマシタ, アイシテ!
野郎銃器ロボはお帰りください。 野郎近接ロボとなおんロボはOK。
>>298 >template<typename E> void foo(std::vector<E> const& x) {}
あーこういう書き方でいいんですね。助かりました。
いつかさらに複雑な選別が必要になったら、mplやconcept checkも
調べてみます。どうもでした。
ちょっとお尋ねした胃のですが void qsort(void* base, size_t n, size_t size, int(*fnc)(const void*, const void*)); という定義がありますが、const void* ってなんなのでしょうか? voidってのは「空の型」ってことだと思うのですが、空のものをconst(固定)するってどういうことなのでしょうか? 何もないのだから固定しようがないと思うのですが・・ また、引数がvoid*になっているのもよく分かりません。void(何もない)のポインタを引数にするってどういうことなのでしょうか??
void*は汎用ポインタ。voidとは関係ない。
>>306 Cでは「何かへのポインタ」をあらわずときに void* を使う。qsort()で
はソート対象の型が決まっていないので、何でも受け取れるように
void*を使っている。
const void* ってのは、「そのポインタが指している先は書き換えしま
せんよ」という意味。
ポインタにはアドレスと「そのアドレスから先にどういうデータが入っているか」という情報が含まれる。 void型ポインタってのは「そのアドレスに何が入っているかを指定しないポインタ」という意味。 受け取った関数内で適切な型にキャストしてやって使うことになる。 qsortはintでもcharでも構造体でもソートできる汎用的な関数にするためそういう形になってる。 constってのは「そのポインタの場所に入ってる変数を変更してはいけません」って意味。 constつけた関数内でうっかり書き換えるとコンパイルエラーになるから、ミスを予防できる。
下記のソースを bcc32 test.cpp でコンパイルすると★の行で エラー2423 存在しないテンプレート'show_array'の明示的な特化またはインスタンス化 *** 2 errors in Compail *** が表示されなす。 存在しないって言われても直前に・・・・ テンプレートの定義が間違ってるのでしょうか?
311 :
310 :2008/03/04(火) 16:31:43
--- test.cpp --- #include <iostream.h> /*-------------------------------------------------------*/ /* 配列の表示テンプレート */ /*-------------------------------------------------------*/ template<class T, class T1, class T2> T show_array( T1 *array, T2 count ) { T2 index; if( count == 0 ){ /* 表示しない ? (YES) */ return( 0 ); /* 非表示 */ } /* 配列を表示 */ for( index = 0; index < count; index++ ){ cout << array[index] << ' '; } return( 1 ); /* 表示 */ }
312 :
310 :2008/03/04(火) 16:32:59
template char show_array( int *array, int count ); ★ template int show_array( float *array, unsigned char count ); ★ /*-------------------------------------------------------*/ /* main関数 */ /*-------------------------------------------------------*/ void main( void ) { int pages[] = { 100, 200, 300, 400, 500 }; float price[] = { 10.05, 20.10, 30.15 }; /* int型の配列 */ show_array( pages, 5 ); cout << '\n'; /* float型の配列 */ cout << show_array( price, 3 ) << endl; cout << show_array( price, 0 ) << endl; cout << '\n'; return; }
unsigned char String[9] = "S2KTI2G7"; unsigned char KeyTable[11] = "0123456789"; char *id = "0"; int i; for(i = 0; i < 8; i++) String[i] ^= *id; このプログラムの動作がよくわかりません たとえばString[0]はSのアスキーコードが83、0のアスキーコードが48なので String[0] = 83^48になるのかと思ったのですが、実際は99になっているようです。 どうして99になるのでしょうか?
>>310 >*** 2 errors in Compail ***
恥ずかしいからちゃんとコピペしようね。
>>313 Cではハット(^)はビット毎の排他論理和演算子なので、83^48はちゃんと99になる。
>>313 83^48
=1010011^0110000
=1100011
=99
>>315-316 なるほど
ここしばらく他の言語しかやってなかったのですっかり忘れてました
すばやい回答ありがとうございます
>>310 こんな感じじゃないかなたぶん
return( 1 ); /* 表示 */
}; <----- ここテンプレートの最後にセミコロンが必要
template char show_array..... → template<> char show_array.....
template int show_array..... → template<> int show_array.....
show_array( pages, 5 ); → show_array<char>( pages, 5 );
show_array( price, 3 ) → show_array<int>( price, 3 )
show_array( price, 0 ) → show_array<int>( price, 0 )
>>310 そのテンプレート関数の目的が意味不明なんだが、取り敢えず「所謂」全角空白が見えるエディタを使おう。
>>310 多分、テンプレート関数では配列の一部を出力してその有無を返すだけと判断して勝手に修正してみた。
--
#include <iostream>
using namespace std;
template<class T> bool show_array(T array[], int N)
{
for (unsigned ic = 0; ic < N; ++ic) {
cout << array[ic] << ' ';
}
return N != 0;
}
int main( void )
{
int pages[] = { 100, 200, 300, 400, 500 };
float price[] = { 10.05, 20.10, 30.15 };
/* int型の配列 */
show_array( pages, 5 );
cout << '\n';
/* float型の配列 */
cout << show_array( price, 3 ) << endl;
cout << show_array( price, 0 ) << endl;
cout << '\n';
return 0;
}
321 :
320 :2008/03/04(火) 17:09:21
いかん、配列の要素数を勝手に取得するバージョンの名残で引き数Nが大文字だw ついでなんで、そのバージョンも貼っておこう。 -- template<class T, size_t N> bool show_array(T (& array)[N]) { for (unsigned ic = 0; ic < N; ++ic) { cout << array[ic] << ' '; } return N != 0; } -- これだと、show_array(price)で使える。でも戻り値の意味がないw
322 :
306 :2008/03/04(火) 17:33:00
なるほど。 レスくださった方々、わかりやすい説明ありがとうございましたm(_ _)m
323 :
310 :2008/03/04(火) 17:34:28
レスありがとうございます! 314 >> あ、aが余分でした (;ω;`) 318 >> テンプレートの最後にセミコロン付加 templateの後に<>付加 show_arrayの後に<型>付加 をやってみましたが、エラー内容は変わりませんでした・・ 319 >> 練習用に色々やってみた感じで作りました。 エディタはさくらエディタ使ってます。 320 >> > 多分、テンプレート関数では配列の一部を出力してその有無を返すだけと判断して させたい動作はその通りです。 320さんのソース読んできます。
324 :
310 :2008/03/04(火) 17:36:39
アンカーの付け方まちがえたぁぁ〜
>>324 全角空白を見えるようにしろって言うのは、>320に全角空白が入っているからなんだが。
# 勿論、後から追加したであろう★印のところ以外にね。
326 :
325 :2008/03/04(火) 17:48:15
いや、全角空白が入っているのは>320じゃなくて>310だった_/ ̄|○
327 :
310 :2008/03/04(火) 17:57:39
>>320 さんのソースを元に、自分との違いを考えて
>>311-312 のソースの★の記述を削除し、
>>318 さんの変更を加えたら、コンパイル通りました〜。
ソースの書き方がコテコテ素人なんで、
>>320 さんのソース見て勉強します。
>>318 さんの追加が無い場合はエラーが出るのですが、内容読んでも
show_array<char>( pages, 5 ); の<char>が何で必要か
わからんです、ヒントお願いできないでしょうか。
エラー内容は↓です。
エラー2285 show_array<T,T1,t2>(int *, int)に一致するものが見当たらない
>>327 template<class T, class T1, class T2> T show_array( T1 *array, T2 count )
というテンプレートがあるので、show_array( pages, 5 ); は
show_array<char, int*, int> かもしれんし
show_array<int, int*, int> かもしれんし
show_array<long, int*, int> かもしれんし
T1とT2は引数見ればわかるけどTの型は決定できないので
329 :
310 :2008/03/04(火) 18:03:50
>>326 !? お
template<class T, class T1, class T2>と
T show_array( T1 *array, T2 count )
の間に全角空白が!!!!!!
コピペした後に入れちゃったみたいです。('A`)
ご指摘ありがとうございます。
330 :
310 :2008/03/04(火) 18:13:08
>> 328 なるほど! 分かりやすいご説明ありがとうございます。 試しに <char>show_array( pages, 5 ); してみたら、構文エラーでしまた。 show_array<char>( pages, 5 ); って書き方なんですね。 ご回答下さった皆様、ありがとうございました(。。)゛
oprator void *() const { if (state&(badbit|failbit)) return 0; return (void *) this; } のopratorはここではどういう意味で使われているのでしょうか? この位置にあるのを初めて見まして、よくわからないんです。
>>331 例えば
class Foo {
public:
operator int() { return 42; }
};
main() {
Foo foo;
int x = foo; // <-- ここ
cout << x;
}
というふうに、クラスを別の型に変換するときに呼ばれる。
ちなみに、このvoid*への変換演算子は if (str)のように条件式で用いるために用意されている。 なぜoperator boolでないかというと、boolでは整数へ変換できてしまうから。 int x = str;のような想定外の変換を行わせないためである。
335 :
デフォルトの名無しさん :2008/03/04(火) 23:21:45
C#で開発したプログラムを、事情で一部C++.Netで書き直さないといけなくなったのですが [C#] List<int[]> foo; の書式が、C++.Netではどう直せばいいのかわかりません。 intの配列ではテンプレートを適応できないのでしょうか?
>>335 List<array<int>^>^ foo;
338 :
335 :2008/03/04(火) 23:25:39
>>336 ありがとうございます。私の4時間が返ってきた。
これで作業が続きます。
339 :
336 :2008/03/04(火) 23:40:27
>>338 ちなみにあなたが書いてるのはC++/CLIなので
分らないことがあったらC++/CLIスレに行くと幸せになれるかも。
List<array<int>^>^ foo; 笑ってるように見えて何かムズムズするw
List<List<List<array<int>^>^>^>^ foo = gcnew List<List<List<array<int>^>^>^>();
積年の疑問なんですが、スタックサイズはいつどうやって決まるんでしょうか。 1. コンパイル時に 2. リンク時に 3. 実行時に a. 自動的に(コンパイラとかが自動変数の使用状況などを見て) b. 固定的に 多分、どれかに当てはまると思うんですが。
343 :
デフォルトの名無しさん :2008/03/05(水) 00:40:00
コンパイルしたら
>>342 環境依存。
Windowsはリンク時に実行ファイルのヘッダにサイズが書かれるんだった
かな。子スレッドのスタックは実行時。
>>342 Windowsではexeにスタックサイズが書かれるので、リンク時以前
組み込みなんかでリセットベクタもコンパイルする必要がある場合は、コンパイル時
と思う。
組み込みで開発してたときはスタックサイズのチェックしてたな どこまで上ってきてるか心配だったから。 あのときはコンパイル時だな。
うちもスタックポインタのチェックやってる。んでも、リンク時だと思う。 リンク時にスタックポインタの開始アドレスとかグローバル変数の確保領域アドレスとかの設定ファイルを使うから。
>>347 そうだな。何とか形式のファイルのサマリーを
出してくれるツールがあったな。
よく、C++ における class と struct の違いはデフォルトで private か public かの差しかないって言うけど、本当? class だと継承やらの情報を管理するための暗黙のメンバが最初にくっつかない? class C {int a;} struct S{int a;} C c; S s; を実行してデバッガで c と s の中身見てみるとメンバ違わない?
350 :
デフォルトの名無しさん :2008/03/05(水) 03:10:19
クラスはメンバ関数や、オーバーロードが使えるだろ 構造体の拡張だろう
本とかだと、class と struct はデフォルトの可視範囲が異なるだけで、 コンパイラレベルでは全く同一ですと書いてある。
>>349 structも継承できるのに何でそこが違うとおもったんだ?
353 :
デフォルトの名無しさん :2008/03/05(水) 03:16:27
細かいことは気にするな 使う側として同じなら構わないだろう
>>349 大抵の実装では、仮想関数を持つクラス・構造体は、
仮想関数呼出のためのテーブル (vtbl)へのポインタを隠し持っているが、
これもクラス・構造体どちらでも同じ。
規格でも構造体とクラスは完全に同一視され、
構造体について何か独立した規定は存在しない。
全てクラスとしてまとめられている。
full bokko
そして大抵の実装では 仮想関数を持たないクラス・構造体は vtbl へのポインタを持っていない。
>>347 H8やSHでは#pragma stacksize XXX というのがあるので、
スタックサイズはコンパイル時、スタックアドレスはリンク時ということかな。
struct S{ int m_a; int m_b} として m_b に代入しようとして void hoge(void *s){ int offset = sizeof(int); unsgiend char * p = (unsgiend char *)s; int * m_b = p[offset]; *m_b = 1234 } みたいなコードが書いてあると位置がずれて死ぬ訳か
struct S { int a; int b; void clear() { ZeroMemory(this, sizeof(*this)); }; } こういうのもマズイ?
>>360 いつか POD の規則から外れる変更を加えたときに忘れずに修正する覚悟が必要。
vectorとか追加した場合ですね。 上のほうで出てた、仮想関数を持つクラスを継承して vtbl へのポインタを持ってる場合は>360で問題無しですか?
>>362 仮想関数を持ったものも POD から外れる。
>>357 HEWでそれやってたな。てかconfig入力画面でメモリセクションのカスタマイズできた。
struct S { std::vector m_v; } s; で ZeroMemory(&s, sizeof(S)); ってやって死んだ事がある
コンパイラBCC55 class PPP{ public: union{ struct{ int n; struct{ enum Hoge hoge; int x; }aa[32][32]; LPCWSTR name[256]; }a; struct{ int p; char i; float y; Hoge *o; }b; struct{}c; }data; }; こんな共用体がクラス変数になってる時に PPP ppp; とするとそこでプログラムが例外も吐かずに落ちてしまいます。 しかし、PPPを他のクラスのクラス変数として宣言しておけば落ちません。 class Hoka{ PPP p; }; 分かる人おながいしまつ・・・。
ちなみにenum HogeはPPPの中で定義されてます。すいません
現象が再現する最小限のソースうp
今更ですが
>>290 のことで
vector<int> num;
num[i*j]=a;
でnum.size()が不定のとき(i*jより小さいときもある)場合
先にnum[i*j]を確保して、num[i*j]=aを入れればよいのでしょうか
確保の仕方を教えてください
>>369 num.resize(100) とかで好きなサイズに変更する
num.resize(i*j)っていうのも可能ってことでしょうか?
>>368 最小限が分かりづらいのでエラーの出ないnewで代用しました。
>>371 可能だが resize(i*j) ではサイズが足りないと思うぞ
374 :
デフォルトの名無しさん :2008/03/05(水) 16:14:35
もっとも使われていないバッファを解放したいのですがSTLなどで良いライブラリはありますか?
>>374 せめてもうちょっと具体的に言わないとどうにもならないと思うよ
LRUを実装するのに適したコンテナはどれでしょうかってことだとエスパーしてみる JavaのLinkedHashMapみたいなやつ? STLにそれはないから、mapとlistを組み合わせるのかな・・
3次元配列(texture)を動的に確保しようと if( (int)texture.size() < ( temp[0] + temp[1]*maxValue[0] + temp[2]*maxValue[0]*maxValue[1] ) ) texture.resize(temp[0] + temp[1]*maxValue[0] + temp[2]*maxValue[0]*maxValue[1]); texture[temp[0] + temp[1]*maxValue[0] + temp[2]*maxValue[0]*maxValue[1]] = num; こうしたら、格納されません。 現在の3次元配列の幅よりも、大きいのが出てきたら値を取り直して、入るべき所にぶち込む ってことをやりたいだけなのですが
>>377 サイズが 10 だったら、有効なインデックスは 0〜9 だ
サイズが temp[0] + .... *maxValue[1] だったら、
有効なインデックスは 0 〜 temp[0] + .... *maxValue[1] - 1 までだ
>>378 ありがとうございます、それが抜けていました
ただ 0 0 0 があったときに格納できないというエラーが出てきて
後少しなのに
class Aを例外として投げるとき throw new A; のようにnewで生成して投げるのと throw A(); と投げるのはどっちが良いのでしょうか?
自プロセスのHWNDを取るにはどうしたらいいのでしょうか?
むかーしどっかで見たのですが、3次元以上の配列は使わない方が良いってどういうことでしょうか? ソースがどこだったか覚えてないのですが、そのときの記憶があり3次元以上はなるたけ使わないようにしてる原状です
あんま多いと気づかずやらかす類のバグが増えるかも…しれないけど決定的な理由じゃねえよな
>>382 その配列が表すモノが本質的に3次元以上のモノなら3次元配列で良いけど
構造体やクラス等で表すべきモノを配列にしてしまうのは避けるべき
数値計算で添字3つ以上の行列とか扱わない限り、 まず必要になることはないと思うけどね。
>>380 newするとどこかでdeleteせんといかんよ。
389 :
デフォルトの名無しさん :2008/03/05(水) 22:04:19
#define SAFE_DELETE(p) {delete (p); (p)=NULL;} を定義して、 SAFE_DELETE(ptr); とすると「構文エラー : ';' が〜の前にありません」のエラーになってしまいます。 delete ptr;なら普通にコンパイルできるのですが、 どこが悪いのでしょうか。
ちょっと行き詰まってしまったので質問させて下さい。 VC2005、WinXP64で以下のようなプログラムを作ったのですが、うまく動いてくれません。 DWORD WINAPI ThreadPrc(LPVOID lpParameter) { while (!ThreadTerminated){ //要求があるまで待機 WaitForSingleObject(hEventHandle,INFINITE); if (ThreadTerminated) break; //共有オブジェクトの排他アクセス WaitForSingleObject(hMutexHandle,INFINITE); //適当に処理 ReleaseMutex(hMutexHandle); //処理が終わると相手に通知 //ここがおかしい SetEvent(hDoneEventHandle); } return 0; } 普段はDelphiでやってますが、64ビットでビルドする必要があったので、Delphiで作ったものをC++に移植しました。 プロセス間通信でいろいろやってるわけなのですが、同じところでいつもタイムアウトしてしまいます。 もちろんINFINITEにするとそのまま固まってしまいます。 32ビットプロセスでSetEventして、64ビットプロセスでWaitForするのは成功するのですが、その逆がうまくいかないのです。 VC固有の問題なのか、64ビットの問題なのか、関係ありそうなのは調べましたが全く原因が分かりません。 この部分さえうまくいけば完成なのですが・・・。 どなたか分かる方いましたらアドバイスお願いします(o*。_。)o
>>389 SAFE_DELETE(ptr);
は
{delete (p); (p)=NULL;};
に展開される。
} の後に ; があるのがポイント。
これで何か起こってんじゃね?
>>389 うちの環境だと普通に動いてしまったよー。
周りを疑ってみるべき
394 :
331 :2008/03/05(水) 22:18:39
なるほど! 分かりやすい説明ありがとうございましたm(_ _)m
395 :
389 :2008/03/05(水) 22:20:21
周りを少し抜き出すとこんな感じです。 -----SystemMacro.h---------- #ifndef SYSTEMMACRO_H #define SYSTEMMACRO_H #define SAFE_DELETE(p) {delete (p); (p)=NULL;} #endif ------List.h---------- #include <windows.h> #include "../system/SystemMacro.h" template <class T> class List { public: virtual ~List(){ if(!_tempFlg) { WORD i; for(i=0; i<_ct; i++) { delete _arr[i]; } } SAFE_DELETE(_arr); //←ここをdelete _arr;にするとコンパイル通る } }; ※Listのメンバ変数は省略してます。
template <typename T> void SafeDelete(T *& p) { delete p; p = NULL; }
なんか怪しげなコードだが _arrの型は?
どーでもいいけど _ は変数名の前につける習慣は良くない。 つけるなら後ろに。
399 :
389 :2008/03/05(水) 22:25:12
あ、_arrがテンプレートの、T**型なのですが、 それが悪いのでしょうか。
fmtflags setf(fmtflags flg, fmtflags mask); 関数の説明で、この関数は flags((flags() & ~mask) | (flag & mask)); のような処理をしている、と書いてあったのですが、 flags((flags() & ~mask) | flag); でも同じではないでしょうか? なぜわざわざ(flag & mask)と書いてあるのでしょうか。
401 :
389 :2008/03/05(水) 22:37:45
>>396 ありがとうございます。
>>397 template <class T>のT**型です。
>>398 とあるJavaのソースでクラスのメンバ変数の先頭に_をつけてたのを真似してます。
C言語はまだ初めたばかりな上、グーグルと2chで全て学んだので、
基礎がなってないのですが、先頭_はなんで不味いんでしょうか。
上のListクラスの機能は、たぶんstd::vectorとほぼ同じです。
標準ライブラリというのを知らなくて、作ってしまいました。
>>400 > 同じではないでしょうか?
いや、同じじゃないから。
だれか
>>391 に突っ込んでやれよw
>>401 「_」始まりの単語はシステム予約される可能性があるから。
pは何処から出てきた? でいいのかな。
405 :
389 :2008/03/05(水) 22:49:40
>>403 ありがとうございます。
}の後ろに;をつけても、うちの環境では動きました。
レスありがとうございます。 fmtflags setf(ios::hex, ios::basefield); で、 ios::hex が 0x0800 ios::bsaefield が0x0e00 とすると、 ios::hex & ios::basefield で、 0000 1000 0000 0000 と 0000 1110 0000 0000 の論理積なので、 0000 1000 0000 0000 で、結局 ios::hex(0000 1000 0000 0000) そのものと変わらないじゃんと思ったのですが、どこかで勘違いしているのでしょうか。
とりあえず SAFE_DELETE(_arr); を {delete (_arr); (_arr)=NULL;}; に置き換えてコンパイルが通るかどうか。 あと、コンパイラは何?
>>400 flgは立てたいビット、maskはflgの属するフィールドを指定するが、
flgがmaskのフィールドに属さなかった場合に、
余計なフィールドのビットを立ててしまうのを防ぐため。
410 :
デフォルトの名無しさん :2008/03/05(水) 23:24:26
質問させて頂きたいのですが、 このように宣言しましたが、 char a[] = "1234"; char b[] = "4567"; char* abc[2][255]={ a, b }; *abc[1]で値が取り出せません。 こういうやり方は無理でしょうか?
>>410 abcはポインタが二次元に並んだ配列だが、それでいいのか?
やりたいのは、ポインタの一次元配列のように見えるが。
つまり、こう。
char* abc[2] = {a,b};
そうしたら、
*abc[0]は'1'
になる。
>399 >あ、_arrがテンプレートの、T**型なのですが >395を見ると delete _arr[i]; とあるから、_attrは new[] で確保したアドレスを前提としていないか? それなら delete ではなく delete[] とすべき。 コンパイルエラーの件とは無関係だが。
413 :
デフォルトの名無しさん :2008/03/05(水) 23:55:17
411> おっしゃるとおり二次元配列のポインタですね。 全然気がつきませんでした。 ありがとうございます。
>389 とりあえず本論とは別だが、その手のマクロは if(flag) SAFE_DELETE(p); else do_something(); みたいにするとエラーになるのでしばしば #define SAFE_DELETE(p) do { delete (p); (p) = NULL; } while(0) のように定義されることが多い。
この場合なら #define SAFE_DELETE(p) ((void)(delete (p), (p) = NULL)) でもいいと思うけどね。 まあ、式中に書けるのが嫌だというのであれば、 do-while 使ったのでもいい。
SAFE_DELETEを使ってるのを見ると ああ10年前に学ぶのを止めてしまったんだなと分かる 自分自身がSAFE_DELETEされてしまったんだ
>416 ちなみにトレンドは?
416じゃないけどshared_ptrとかじゃないの
ずっと前から auto_ptr と vector によって delete の出番はほとんど無くなっている。
420 :
417 :2008/03/06(木) 04:10:27
ああ、そういう意味でか。勘違いしてた、さんきゅ。
421 :
デフォルトの名無しさん :2008/03/06(木) 06:12:17
ガベージコレクションの緩いやつの理論はありますか? たとえばファイルに書き出すために複数のバッファを用意したとして もう書き込みが発生しないだろうと予測されたら書き出してメモリを解放するというやつです
422 :
デフォルトの名無しさん :2008/03/06(木) 06:15:54
100ファイルに書き込みがあって試行するうちに総数の10%のみの書き込みだけになったら それ以外は書き込みがないだろうと思って解放したいのですが、タイミングをいつにするか具体的に計算する方法は ありますか
LRUでぐぐればいいんじゃない?
424 :
デフォルトの名無しさん :2008/03/06(木) 07:02:10
ちょっと違うんです たとえばバッファは10個なら、10個前が一番古いですが、11個目の後 1〜10番が続くかもしれないじゃないですか もっとも利用されなかっただけではなく、バッファサイズを増したほうがいいかも調べたいんです
最終使用時間を記録しといて、N秒以上使われてなかったら削除 とかでいいんじゃない?
質問でございます。 int* A_PTR = new int[5]; として確保した領域の、たとえば、A_PTR[3]のような、 途中の領域だけ解放(delete)することは可能でしょうか?
429 :
427 :2008/03/06(木) 16:59:15
>>428 やはり無理なんですね。
別のポインタに入れてからdeleteなど、
いろいろ実験していて気が狂いそうでしたので
大変すっきりしました。
れす、ありがとうございました。
CString cstr; unsigned char uc[sizeof(cstr)] = (unsigned char)(LPCSTR)cstr; コンパイル通りません。要は、↓を動的にしたいです。 unsigned char uc[10]="0123456789"; よろしくおねがいします
配列のサイズを動的に変えるのは無理です。 ヒープで取って良いのなら、 char* uc = new char[文字列の長さ+1]; strcpy(uc, コピーしたい文字列へのポインタ) でもしてください。
これではだめ? unsigned char* uc = (unsigned char*)(LPCSTR)cstr;
433 :
430 :2008/03/06(木) 18:04:24
>>431 やっぱり無理ですか。。
>>432 uc[0],uc[1]みたいに、ポインタではなく配列としてアクセスしたいんですよね。。
なんか根本的に駄目なソース書いてる気がしてきたので、発想を変えてみます。
どうもありがとうございました。
動的に大きさを変えたいならstd::vector使えばいいやん。
あ、文字列ならstd::stringな。
>>433 添え字演算子はポインタでも使えるけど。
>>433 E1[E2] は *((E1) + (E2)) の syntax sugar だ。
uc[0] → *(uc + 0)
uc[1] → *(uc + 1)
uc[0] → *(uc + 0) → *(0 + uc) → 0[uc] uc[1] → *(uc + 1) → *(1 + uc) → 1[uc]
>>438 さんざん既出
"0123456789ABCDEF"[i]
を大昔はやっていた。
それは関係ないだろう・・・。 i["0123456789ABCDEF"] ならともかく。
あま〜〜〜い
443 :
389 :2008/03/06(木) 22:58:20
みなさん色々とアドバイスありがとうございました。
>>408 通ります。Visual Studio.NET 2003を使ってます。
>>412 _arr = new T*[_max];という感じで確保してます。
delete[] は使ったことないですが、やってみます。
>>414 それは思いつきませんでした。
>>415 その書き方は初めて見ました。
>>416 10年前というか、C言語始めてまだ1ヶ月半なんですが。。。
アレだ、「個体進化は系統進化を繰り返す」
445 :
デフォルトの名無しさん :2008/03/06(木) 23:10:44
以下のコードでファイルの2番目のバイトだけを 書き換えようとしたんですが 全く何も代わりません #include <stdio.h> int main(void){ FILE *fp; char cIn; char cOut = 'X'; int cnt; fp = fopen("test.txt", "rb+"); fread(&cIn, 1, 1, fp); printf("%c\n", cIn); cnt = fwrite(&cOut, 1, 1, fp); printf("%d\n", cnt); fclose(fp); return 0; } <test.txtの内容↓> ABCDEFG <出力結果↓> A 1 これはどう理解したらいいんでしょうか? BCとVCで試してみました
freadしてA読んで、表示した(出力1行目) fwriteして次のBをXで上書きして、(test.txtの中身変化) 要素数の1が戻ってきて表示(出力2行目) 何が不思議なんだ?
>>445 readからwriteに切り替える時、もしくはwriteからreadに切り替える時は
必ず間にfseek()を挟む事。
>>445 コンパイル君のぼやき
「freadとfwriteに&使わないで下さいよ。あと、辞書ぐらい買ってくださいよ。
何でもかんでも私に聞かないで下さいよ。なんでもかんでもプリントにしないでくさいよ。
宣言するんだったらまともに宣言してくださいよ。main関数の引数ぐらい使ってくださいよ」
Visual C++についてなのですが、 分割コンパイルについていまいちよくわかりません。 main.ccp ClassA.ccp Def.h ClassA.h resource.h と5つあって、 main.ccpではDef.hがインクルード、 ClassA.hでもDef.hがインクルードされ、Classの宣言と、インラインでのメンバの定義、 ClassA.ccpではClassA.hとDef.hがインクルードされています。 また、Def.hではresource.hがインクルードされているほか、#ifdnefを使って重複しないようにしています。 ビルドをすると、C2143構文エラーなど、ものすごい沢山のエラーが出てきてしまいます。 このようにヘッダとソースファイルを分割する場合、どのようにインクルード等をすればよいのでしょうか。
> ClassA.ccpではClassA.hとDef.hがインクルードされています。 とりあえずこのDef.hはインクルードしなくていいいような・・・
>>449 その文面だけを見る限り、ファイル分割のしかたもインクルードの仕方
も問題ないよ。エラーが出るのはファイルの内容がどこか間違っている
とか、何かの定義が足りないとか。
452 :
デフォルトの名無しさん :2008/03/06(木) 23:51:02
newを使って確保した領域をポインタとして返す関数を作ったんですけど、開放するにはどうすればいいんですか? 個人的には↓の方法でできるような気がするのですが、できるかどうか心配なので教えてください char *func(){ char *buf = new char[1024]; //bufにデータを入れる return buf; } int main(){ char *ptr = func() //ptrであんな処理やこんな処理 delete [] ptr; }
膨大な数のエラーと聞くと、本当に何か書き間違えている気がする。
454 :
デフォルトの名無しさん :2008/03/06(木) 23:55:48
初心者も上級者もnew使うならクラスでつかえよな 解放する方法を間違えたり、しなかったりする クラスならデストラクタがする
>>452 どうでも話にはなるが、
メイン関数のファンクがカマを彫られたって泣いてるが、
わかっててほられたのかほられてないのか気になる。
>>452 それで特に問題はないが、
void func(std::vector<char>& buf) {
buf.resize(1024);
// buf にデータを入れる
}
int main() {
std::vector<char> buf;
func(buf);
// buf であんな処理やこんな処理
}
とやった方が面倒がないし例外とかあっても確実にメモリが解放されるから安全で便利。
日本語はおかしいが、要するに RAII ってことじゃね?
459 :
デフォルトの名無しさん :2008/03/06(木) 23:58:43
string buf buf.reserve(1024) &buf[0] でも良い
それはちょっと・・・。 length 変わらないじゃんか。
>>451 あってますか…
1行目初っぱなから
Naive_Grid_Class.cpp(4): error C2143: 構文エラー : ';' が 'NaiveGridCtrl::ChkhCtrl' の前にありません。
などと出てきて(下のようなコード)
#include "DefHeader.h"
#include "Naive_Grid_Class.h"
BOOL NaiveGridCtrl::ChkhCtrl(){
return (BOOL)hCtrl;
}
もう何が何だかさっぱりなんですが…
462 :
デフォルトの名無しさん :2008/03/07(金) 00:01:05
>>457 class ABC {
char *buf;
ABC(){確保}
~ABC(){解放}
};
main(){
ABC x;
}
とやれば簡単って事
呼ばれたタイミングだけでnewしたいとは限らんだろうに
>>461 class NaiveGridCtrl の最後の ; を忘れているんじゃないか?
質問です。 前から思ってたんだけど、 メモリの解放以外にデストラクタって使い道あるの?
466 :
デフォルトの名無しさん :2008/03/07(金) 00:09:25
データの残りを書き出す
リソースの開放
質問です。 C++で住所録を作っているのですがソートができません。 構造体に名前、住所、年齢、電話番号・・・など 項目ごとに入れるところまではできたのですが、 名前、住所、年齢、電話番号・・・など項目ごとに分かれているので、 名前なら名前だけがソートされてしまい他のはそのまま。 名前をソートしたらその順序で他の項目が付いてくるようにするには、 どうしたらいいのでしょうか。
>>468 まず、どうやってソートしてるんだ?
そこのプログラムみせてみ
>>468 え?なんでそうなるのさ?
ソートした順に構造体を並べ替えればいいだけじゃんw
名前だけ入れ替えてるんじゃねw
構造体にしてる意味がねぇw
名前をソートするんじゃなくて、名前のソート順通りに構造体のオブジェクトをソートするんだ。
474 :
デフォルトの名無しさん :2008/03/07(金) 00:33:47
int i = 1; while(i <= 10){ fout[i].open("dat$i.dat"); fout[i] << i <<'\n'; i++; } てな感じでデータファイルを10個作りたいのですが、 ""の内のiは変数と見てくれなくて困ってます。 何かいい方法ありませんか??
>>474 あたりまえだろw
こうすればいい
char filename[100];
sprintf( filename, "dat$%d.dat", i );
fout[i].open( filename );
477 :
デフォルトの名無しさん :2008/03/07(金) 00:37:46
>>468 #include <iostream>
#include <string>
#include <set>
using namespace std;
class memberlist{
public:
string name;
string tel;
string adress;
memberlist(string a, string b,string c){
name=a; tel=b; adress=c;}
bool operator<(const memberlist& a)const{
if(name<a.name)return 1;return 0;}
};
main(){
set<memberlist> x;
x.insert(memberlist("山田太一","030000000","東京都"));
x.insert(memberlist("明石家明","077777777","沖縄県"));
x.insert(memberlist("佐藤一郎","051111111","大阪府"));
set<memberlist>::iterator p;
for(p = x.begin(); p!=x.end(); p++){
cout<< p->name <<" "<< p->tel <<" "<< p->adress <<endl;
}}
>>463 どちらにしろ管理クラスに入れとけば
デストラクタが勝手に delete してくれるだろ。
479 :
445 :2008/03/07(金) 01:06:00
みなさんドモドモ
>>447 それそれ。それです。
fseek(fp, 0, SEEK_CUR);
が必要みたいなんですが
これがわからない。
カレントポジションから0バイト進めるのは
何もしないのと同じなのではないのでしょうか?
OSのAPIなどの場合
readしてそのままwriteする事でファイル位置が
自然に進む事が多い気がする訳ですが
この仕様はよくわからないです
これはC(ライブラリ)の明示された仕様なのでしょうか?
480 :
445 :2008/03/07(金) 01:12:39
そうそう。あと一つ・・・ fwriteで1バイト書き込めたはずなのに その1バイトはどこへ行ってしまったんでしょうか・・・
>>479 APIと違って、バッファリングするのが前提だからfseek()などでバッファを同期を取ることに決められている。
>>461 Naive_Grid_Class.h の最後に ; が足りないとか、
BOOLの定義がどこにもないとか。
484 :
デフォルトの名無しさん :2008/03/07(金) 01:22:57
>>475 そのようにすれば、できました!
ありがとうございます。
>>476 stringstreamも勉強します。
485 :
445 :2008/03/07(金) 01:49:51
>>481 なるほど。仕様ですか・・・
多分FILE構造体の内容とかから必然なのかな?
直感的には把握が難しかったです
>>483 fseekはさめば書き換わりますが、
はさんでなくてもfwriteの結果が1というのが
納得いかず・・・
試しにfread/fwrite/fseek(fp, 0, SEEK_END)
というのもやってはみたけれどやはり書き換わらず・・・
486 :
デフォルトの名無しさん :2008/03/07(金) 02:03:11
int main(){ fin.open("aaa... fout.open("bbb... function(....); } function(.....){ fout << "thanks" <<'\n'; } のようにmain関数でデータファイルを開いて、 function関数の中に開いたファイル持ってきて、書き込みたいんですけど。 どうするのがいいのでしょうか?
>>486 ストリームを引数にとればいいんじゃねーの?
>>486 ストリームを大域変数にすればいいんじゃねーの?
>>486 ストリームを参照で取る
constで取ったらあかんよ
490 :
デフォルトの名無しさん :2008/03/07(金) 03:42:36
>>486 (ofstream& fout[], ifstream& fin[])
ってことですか??
参照型の配列は許されないとかなるんですが。。。
困り果てた。
>>490 何故いきなり配列に? >486では一言もそんな話が……
#include <iostream> これで通る #include <fstream> void sub(std::fstream* f) { f[0]; } int main() { std::fstream f[10]; sub(f); }
494 :
デフォルトの名無しさん :2008/03/07(金) 04:17:54
>>493 すいません、素人目からはさっぱりなんですが。。。
fout,fin???どうなったのでしょうか??
>>494 配列だったらリファレンスではなくポインタで渡せばいいだけの話。
>>494 あんた>486=>490? >489に答えがあるのに、それをどう曲解したのか>490になって、
>491の質問を無視して>494みたいなこと言われても最早誰も対処できないぞ。
もらった回答をすっ飛ばす奴の神経がわからんね。 漢字読むのが面倒臭いからって、上の行↑を「もらったをすっばすのがわからんね」と読んで 「うーん、さっぱりわかりません」とか一人で勝手に困ってるようなものだろ。
498 :
デフォルトの名無しさん :2008/03/07(金) 08:49:37
どっちでもいいといえば どっちでもいいのですが、 現在ゲームを作ってまして、敵の動きを実装するのですが、 C言語で関数のポインタを保持し、タイミングが来たら 保持していた関数を呼び出すのと C++で、基本のクラスを用意し、それから派生してポリモーフィズムで呼び出すのと どちらが良いでしょうか 開発規模は個人なのでそれほど多くならないです、ですがまだ、仕様が決まってないのでなんともいえないのです。 なにが不満かというと Cだと 関数だらけになってしまう C++だと 開発に時間がかかったら保守が大変そうなことです
499 :
デフォルトの名無しさん :2008/03/07(金) 09:01:36
作ったことがないが、C++に一票
500 :
デフォルトの名無しさん :2008/03/07(金) 09:03:21
迷ったらC++。これ鉄則。
>>498 Commandパターン or Callback by template
くだらない質問で申し訳ありません。 namespace myname{ hogehogehoooge; }; //← namespace mymyname{ hagehagehaaage; } //← コンパイル自体はどっちでも通ったのですが、どっちが本来の文法的に正しいのでしょうか。
コンパイラ的には上のセミコロンは空文があるってだけかと
>503 なるほど、納得しました。
物凄くくだらない質問なのですが教えてください double x=1.0; int y = 10000; int z = y * x; この場合z=yって成り立つのでしょうか?
>>505 成り立つよ
浮動小数点の誤差がどうとか言う観点だよな?
はい、そうです ありがとうございました
メンバに変数しかないクラス(ようするに構造体)を継承して、 それらのポインタをdynamic_castしたい場合、親クラスに virtualな関数を無理やり入れておくしかないのでしょうか?
>>508 dynamic_castの意味分かって言ってる?
>>508 手っ取り早く済ませたいならそうだね。
手間がかかってもいいなら、たぶん dynamic_cast の必要性を
見直したほうがいいんだろうけど。
>>509 ,510
関数テーブルで引数が違う関数をまとめる場合に、
引数型を全部派生にして親クラスのポインタを
受け取るようにしとくと、キャストミスも無くて便利かなと
思ったんですが。
多分設計見直したほうが良いパターンなんでしょうね。
デストラクタを仮想にしておけば良いんじゃないかな このパターンで自分もはまったな 引数に<list>をとるか可変長引数とか配列とか色々やり用はあるな
514 :
468 :2008/03/07(金) 16:44:37
http://www.borujoa.org/upload/source/upload17235.txt すみません。ド素人のプログラマですが、質問です。
なるべく上のファイルを利用してファイルソートを行いたいのですが、
これからどうすればいいのかわからず手が止まっております。
ソースではなく文章でいいので答えていただけますか?
filesortがファイルをソートする関数部分です。
つまりVectorとsortを使って何とかしたいわけですが、
この書き方であると要素ごとでしかソートできません。
もちろん要素だけのソートはできました。
なんかあとちょっと弄ればできそうな気がするんですが、
僕の脳ではどうしようもありません。
どなたかご指導ください。
私的にはsetさえ使えば100人力じゃぁみたいな感じになるので、
setを使いたくありません。その点も含めてよろしくお願いいたします。
あとこのソース見て「ここをこうした方がいいのでは?」と思う人はご指摘ください。
よろしくお願いいたします。勉強になります。
開発環境:CentOS 5
コンパイラ:g++
コンパイルエラー:無し
クラスについてさっぱりわかってないからこんなこと思うのかも知れませんが、 クラスの公開メンバ関数のアドレスを外部に教えてあげて、 そこから直接クラスの関数にアクセスすることってできますか? 具体的に言うと、Wik32APIでの、ウィンドウプロシージャに、クラスのメンバ関数を使いたいのですが…
>514 filesortの中身をちらっと読んだだけ。 ・カンマ区切りを取り出す常套手段は 1:スペース記号、タブ記号をすべて別の文字列で一旦置換 2:カンマ記号をすべてスペースに置換 3:stringstreamに流し込んで >> を使って読み込む 4:1:で入れ替えてたのを元にもどす です。こうした方がいいです。 ・名前を入れ替えたいだけじゃないんですよね? 今のあなたのファイルは「名前データを取り出して、それをベクターに格納。そのベクターをソート」 している「だけ」ですよ。 あきらめてsetを使うか、set相当のものを自分で書くか、 そうでなければsort相当のものを自分で書いてください。 ・fin>>temp この部分は、もし入力ファイル中にスペースがあると困るのではないかと。 nameに「Richard Feynman」って入ったら、Richardで切れますけど、いいんですか? 一行取り出したいならgetlineを使いましょう。
>>511 普通の関数は仮想にするなよ
つEffective C++ 第38項
ダウンキャストはやめよう
つEffective C++ 第39項
というかEffective C++を購入して一読する事を強く勧める。
>>515 メンバ関数の実装は、クラスのポインタを引き渡していることが多い。
(thisポインタが引数としてわたっている)。
よって、関数ポインタを取ってきたところで、メンバ以外からマトモに使えません。
>>513 511じゃないが参考までにどういう形で実装するのか教えてくれませんか?
テンプレートを使った経験がないのでどういう風に使うのか見当がつきません
520 :
452 :2008/03/07(金) 18:21:57
>>455-456 亀ですがレスthx
Winsockと同時に使うから文字列をstd::stringじゃなくてchar*で使ってたんですが、
例外処理さえつければ
>>452 のコードで大丈夫ですよね
あと、
>>455 のカマを掘られたって言うのがどうことかちょっと気になるんですが・・・
>>518 やっぱ駄目なんですか。
共通プロシージャ用意してmapしたのを検索する方向で考えてみます。
523 :
デフォルトの名無しさん :2008/03/07(金) 19:42:31
>>523 staticメンバ関数はstaticなメンバしかイジれないじゃん。
>>524 そうだよ。単にクラスという名前空間に閉じ込め、
protected/privateにできるという程度の意味しかない。
どっかからインスタンスへのポインタを得て、非静的なメンバ関数を呼ぶのが
静的メンバ関数のウィンドウプロシージャの仕事。
>>522
526 :
デフォルトの名無しさん :2008/03/07(金) 20:34:15
>>524 オブジェクトを作らずに呼び出そうとしてるんだからメンバなんていじる必要ない気が
527 :
デフォルトの名無しさん :2008/03/07(金) 20:42:15
>>515 サンクという手法でウィンドウプロシージャを書き換えて、ウィンドウハンドルの代わりにthisをスタックに積んでメンバ関数にジャンプさせれば?
boost::function
>>523-527 あ、オブジェクトではなく、クラスにひも付けすればよいのですね。
有り難うございました!
とあるクラスの派生クラス郡の中で一つの派生クラスだけ 関数の引数が異なることになってしまいました こういう場合はどうしたらよいでしょうかorz
設計しなおす
>>531 全クラスに引数増やすとか(そしてデフォルト引数をつけておくとか)、
その派生クラスだけ別のメンバ関数で余分の引数を設定しておくとか、
引数の集合を何かクラスにまとめて、上位の概念に置き換えることで引数を共通にするとか。
dynamic_castしろと悪魔が囁いているぜ
>531 1. きっとやりたいことが間違ってるから考え直す。 2. boost::any とか boost::variant とかでぶちかます。 まぁもう少しやりたいことを詳細に説明するべきだろうね。
536 :
531 :2008/03/08(土) 02:14:02
とある計測器と連携して、とあるプロセスを監視してそのデータをモニタに表示するのですが 今回のプロセスだけ表示させたいパラメータの数が増えてしまいました 監視プロセスが複数同時に走っていて、そのうち3つを同時に表示するようにするため 表示対象をユーザーが切り替えられるようにするため 表示クラスに監視クラスのポインタをつかって保持させています 監視クラスに GetData(int OutputA, int dataB,int dataC) という関数をよういしていたのですが 最新の計器が監視できるパラメータが増えてしまって・・・orz
>>536 そのシグニチャでGetだと言うのなら、参照かポインタ渡しじゃないの?
まあそれはいいとして。
パラメータの種類を指定して、データを1種類だけGetする関数を作ったら?
538 :
デフォルトの名無しさん :2008/03/08(土) 02:38:59
void calc(int& m, fstream* fio); int main(void) { fstream fio[10]; char filename[10]; int m, steps; steps = 7; fio[0].open("calc0.dat"); m = 1; while(m <= steps){ sprintf(filename, "calc%d.dat", m); fio[m].open(filename, ios::in | ios::out); m++; } m = 1; while(m <= steps){ calc(m, fio); m++; } return 0; }
539 :
デフォルトの名無しさん :2008/03/08(土) 02:43:13
void calc(int& m, fstream* fio) { int i, j; int a, d[100]; j = 1; while(j <= 3){ fio[m-1] >> a; d[j] = a; j++; } j = 1; while(j <= 3){ fio[m] << d[j] <<' '<< j <<'\n'; j++; } } calc0.datの中身 5 16 77 基本的にすべてのデータファイルが同じになるようにプログラムを書いたのですが。 うまくいかないです。どこか間違っていますか?
540 :
デフォルトの名無しさん :2008/03/08(土) 02:43:52
void calc(int& m, fstream* fio) { int i, j; int a, d[100]; j = 1; while(j <= 3){ fio[m-1] >> a; d[j] = a; j++; } j = 1; while(j <= 3){ fio[m] << d[j] <<' '<< j <<'\n'; j++; } } calc0.datの中身 5 16 77 基本的にすべてのデータファイルが同じになるようにプログラムを書いたのですが。 うまくいかないです。どこか間違っていますか?
>>540 >どこか間違っていますか?
あんたの説明。
結果がどうなったのか、どうなるつもりだったのか(これは全てcalc0.datと同じになるということか)、
実行した環境と処理系は何か、位のことは書いても罰は当たらんよ。
542 :
511 :2008/03/08(土) 11:33:07
昨日の続きなんですが、引数のの違う関数を まとめた関数テーブルって、どう実装するのが 良いでしょうか? >512のようにlistや可変長引数だと、個数が 違う場合には有効ですが、構造体を渡す場合には 無理があると思えます。 (構造体の要素をPOD型に分解してlist化するとか?) >513で書かれた特殊化では、どう実装するのかが 全く閃きませんorz キャストを使う以外で違った構造体やクラスを スムーズに(できれば低コストで)渡す方法ってあるのでしょうか?
>>542 昨日の続きと言われても状況を把握するために過去に遡って読むのは面倒なので目的を詳しく。
まぁ、よくあるGUIライブラリの実装などでは構造体を丸ごと渡すのではなく汎用ポインタを渡す形が多いけどね。
544 :
511 :2008/03/08(土) 11:42:33
なお今自分が使ってた方法だとこんな感じです。 class ArgBase { //引数親 public: virtual ~ArgBase(){}; } class Arg1 : public ArgBase { public: int arg; } //以下必要なだけArgBaseを引き継いだ構造体を作る //関数テーブル typedef bool(*pFunc)(ArgBase*) FUNCPTR; FUNCPTR fuctable[10]; fnctable[0] = Func1; //関数例 bool Func1(ArgBase *pArg) { //これがArg1が必要な関数なら Arg1 *ptr = dynamic_cast<Arg1*>(pArg); if(ptr == NULL) return FALSE; //処理 return TRUE; }
545 :
デフォルトの名無しさん :2008/03/08(土) 15:49:36
久しぶりにプログラムを組むのですが、初歩的なことが分からないので 教えてください。昔 float a; a=1.0 と1ではなく1.0にしなさいと教わったのですが、その詳しい理由を 忘れました。 どうしてなのでしょうか?
>>545 1.0も中途半端だな。1.0fと書け。
1と書くとそれはint型になる。
1.0と書くとdouble型になる。
1.0fと書くとfloat型になる。
intやdoubleからfloatへの変換は警告が出る可能性があるので、
代入先と同じ型にしておけということ。生成される機械語は同じだろうけど。
>>543 やはり間違わないように気をつけてvoid*で渡してキャストするのが
常套手段なんですかね。
あと、 typedef bool(*pFunc)(ArgBase*) FUNCPTR; じゃなくて typedef bool(*FUNCPTR)(ArgBase*); でしたorz
549 :
デフォルトの名無しさん :2008/03/08(土) 17:09:29
現在、勉強がてらに、Windows用のクラスライブラリを無意味に作ってるのですが dynamic_castって良い機能ですねぇ 基本クラスに無意味に仮想関数を突っ込まなくても、派生クラスの機能が使えるなんて嬉しすぎる
dynamic_cast禁止
は?
すげークラスライブラリきた
俺も今無意味にgtkのラッパークラスライブラリ作ってるよ! Window wnd("sample",MAIN_WINDOW); vBox box(MAIN_WINODW); Label sample_label("sample",MAIN_WINDOW); Button ok_button("OK",MAIN_WINDOW); CREATE(MAIN_WINDOW); ok_button.clicked(func); box << sample_label << ok_button; wnd << box; CONSTRUCT(MAIN_WINDOW); みたいにmain関数の中で書いたらコンパイルが通るようになるやつ。 今マニピュレーター実装中。
これだから演算子多重定義が叩かれるわけだ。
>>550 ごめんねごめんね(*‘ω‘ *)
void __fastcall TForm1::N1Click(TObject *Sender) {
TMenuItem* menu = dynamic_cast<TMenuItem*>(Sender);
switch(menu->GroupIndex) {
case 1:
switch(static_cast<TSortDirection>(menu->Tag)) {
case sortLarge:
break;
case sortSmall:
break;
}
break;
case 2:
switch(static_cast<TLogOutputMode>(menu->Tag)) {
case logList:
break;
case logSingleLine:
break;
}
break;
}
UpdateTitle();
}
Cらしいプログラムですなあw
これなら適切にdynamic_castを使っている場面に見える。
TForm1とかN1Clickとかいただけない
すみません。えらく単純な質問なんですが、 C++で「なんでもいいからキーを押すと続行」 というのはどうすれば実現できるのでしょうか? 文字列や数字を読み取らせる方法は知ってますし、 ググればいくらでも出てくるのですが、 「いったん入力待ちしていかなるキーを押しても構わず実行」 という風にしたいのです。 もちろん数字読み取らせて適当な数+ENTERという風に組めば 手間が増えるだけで大体同じことはできるます。 しかし、あるデータの異常値の原因を調べるため、 異常のたびにそのデータをグラフにして打ち出させたいんですが たぶん三万回くらいやらなきゃならないんです・・・
OSによる
そこでpdcurses(ncurses)
enterキーのみ反応でいいならgetchar()でもなんでもいけそうな気がする
563 :
560 :2008/03/08(土) 18:33:28
ありがとうございます。getcharでいけました
564 :
デフォルトの名無しさん :2008/03/08(土) 18:33:56
>546 ありがとうございます。 元がfloatなのにいらないお節介しなくても良さそうなのに。
559の間違いです。すいません
566 :
デフォルトの名無しさん :2008/03/08(土) 18:46:22
msxml6.dllを使ってXMLのデータを取得しようと思っているのですが、 要素の属性の取り方だけ分かりません。 どのように取り出せばいいのでしょうか?
>>564 >元がfloatなのにいらないお節介しなくても良さそうなのに。
大きな勘違いをしている悪寒。
もうなんて言うか、初心者とかそういうレベルですらないんですけど、 昨日小一時間このミスに気づかなくてバグと死闘していたので… int a,c,x; unsigned int b; x = max(-c, min(x, a - b)); としたとき、 (a-b)がunsigned intとして評価されてしまうのですが、 こういうとき、オペレーターの戻り値の語ってどうやって決まるんですか? どこかの本では、大きい方に丸められるとか何とか書いてあった気がするんですが… 実際どのような規則になっているんでしょうか?
>>568 算術型の標準変換、整数の格上げとか
そんなもんどの本にも載ってるだろ。
>>564 >元がfloatなのにいらないお節介しなくても良さそうなのに。
もとがdoubleの値(1.0)をおまいが勝手にfloat型の変数に入れようとしているのを
コンパイラさんは(おせっかいかなと思いながらも)教えてくれようとしている。
レベルアップするためにも、人の忠告は素直に聞こうな。
サルなら反省できる
>>570 は正しい事を言っている気がするが
オレも読解力がないのだろうか
皆無
レスをたどると元々は float a = 1; のような気がする
>>577 それだとfloat変数の初期化だよね。
もともとは以下のようにfloat←doubleの代入だったはず。
>float a;
>a=1.0
>>569 持ってる本は2冊ともunsignedまでは書いてないんだが…
駄目なの使ってるのね…(一つは学校指定だけど)
算術型 標準変換 でググったら見つかりました、有り難う。
long double > double > float > unsigned long int > long int > unsigned int > int
int > unsigned int だとばっかり思ってた。
(表現力が大きい方に…ってかいてあるからマイナスが表現できる方が上なのかと…
よく考えてみたら、表現できる値の絶対値はunsignedの方が大きいけど。)
>>566 DOMだったら、selectNodesとかselectSingleNodeとかを使えばいいよ。
581 :
デフォルトの名無しさん :2008/03/08(土) 21:20:47
>578 最初に書き込んだものです。 多分みなさんが思っているよりもっと初歩的なことが 分かっていないのだと思います。 正直doubleとfloatの違いが精度の違いでfloatがメモリ確保の ためだけに使われるぐらいにしか考えていません。 情報落ちや桁落ちの問題でここまでするのでしょうか? 正しい解釈はこうですか? int a; float b; double c; a=1; b=1.0f; c=1.0;
582 :
デフォルトの名無しさん :2008/03/08(土) 21:23:45
>581 すいません。もう少し質問させてください。 何のためにここまでするのかと言う部分です。 情報落ち、桁落ち、丸め誤差、その他 このうちのどれですか?
おっもくそ大量の数値データを扱うときはdoubleじゃなくてfloatにするなぁ・・・ で、単純に、floatを準備したからにはfloatを突っ込む。と。
>>581 何をどう解釈しているのか分からないが…。
1や1.0などの定数自身も型を持っていることは理解している?
その定数をどの型の変数に代入するかに無関係に、定数自身が型を持っている。
1 ← int型
1U ← unsigned int型
1.0 ← double型
のように。
>情報落ち、桁落ち、丸め誤差、その他
この場合は、その他。
実数の1.0という値は、double型でもfloat型でも桁落ちも丸め誤差もなく正しく表現できる。
ここで指摘されているのは、定数の書式としてfloat型の定数を表現できるのだから
それを使用したほうが適切だろう、ということ。
精度の大きい型の値を精度の小さい型の変数に代入しても、桁落ちなどがなければ全く問題ない。
桁落ちなどがあるとしても、それを意図して書いているなら動作としては正しい。
でも意図したものかどうかプログラムを他人が読んでも分からないので、そのような場合は明示的なキャストをしたほうがいいこともある。
この場合はキャストなんかせず、定数を明示的にfloat型で書けばいい。
定数の1は整数型だが、実数に変換しても何にも問題ないので int a = 1; float b = 1; double c = 1; としてしまうなぁ。 # ただし、float b = 1.0としてしまうとdouble値からfloat値からのキャストになるのでコンパイラによっては巧くないね。
586 :
デフォルトの名無しさん :2008/03/08(土) 22:09:18
>584-585 早速のレスありがとうございます。 よく分かりました。 >この場合は、その他。 >実数の1.0という値は、double型でもfloat型でも桁落ちも丸め誤差もなく正しく表現で>きる。 そう思っていたのに何故そこまでこだわるのだろうと思っていたら、 定数の型のことを言っていたんですね。
587 :
デフォルトの名無しさん :2008/03/08(土) 22:20:53
マルチスレッドのプログラムでSTLは使えないと聞いたのですが、本当ですか? あと、_PTHREADSをdefineすれば使えるとも聞いたのですが、、、 googleしても、結構昔の情報が多くて実際のところはどうなのかよく分かりませんでした。
588 :
デフォルトの名無しさん :2008/03/08(土) 22:23:39
FedoraとWindowsでソースレベルで100%互換のアプリケーションを 作ろうとしているのですが、現実的ではないでしょうか? またどの辺に気をつけて開発した方が良いでしょうか? 内容は不特定多数のPCとsocket通信でバイナリデータをやりとりし、 内部でPostgreSQLにアクセスする、いわゆるサーバアプリケーションです。 開発はほぼ全面的にWindows側(VisualC++.net2003)で行い、 1日2度程、Fedoraでも動作テストをする予定です。
かつてKylixという開発環境があってですね
>>588 完全に.NET上に載せてしまってMONO使うとか。
俺は使ったことないけど
一つお伺いしたいのですが,FLVなどの動画をweb上からdownloadし, てローカルに保存するプログラムを作りたいのですが, どのようなライブラリを使えばいいのでしょうか? ライブラリなどなく自分で作るしかないのでしょうか?
593 :
デフォルトの名無しさん :2008/03/09(日) 04:02:45
ダウンロードするライブラリはあるが、アドレスを発見するライブラリはない
レスありがとうございます. アドレス入力は手動でやろうと思っています. ダウンロードするライブラリはあるんですね.ありがとうございます
595 :
デフォルトの名無しさん :2008/03/09(日) 04:14:05
Youtubeの動画がおいてある場所がわかれば ZIPやEXEやAVIやMP3を落とすのと同じ 場所がわからなければ無理 動画が見られるアドレスと違う
>>588 ソケット通信をどうにかする必要がある。
WindowsとPOSIXで似て非なるAPIを持っているから、
自分でラップするなり既存のライブラリを使うなりしないといけない。
598 :
デフォルトの名無しさん :2008/03/09(日) 09:51:30
先にSTLについて質問したものです。 教えてもらったファイルとかを見てみたのですが、マルチスレッド環境で std::cout に何かを書き出す時、いちいちロックをとらないとだめなようですが、 ロックの必要ないcout相当のものはないでしょうか? 自分でinline関数を作ってつかうようにはしたのですが、、
599 :
デフォルトの名無しさん :2008/03/09(日) 10:33:05
ごめんマクロだった boost::mutex mutex_io; #define safe_cout(m) { \ boost::mutex::scoped_lock lock(mutex_io); \ m \ } int main() { safe_cout( std::cout << "hello" << std::endl; ); こんな感じ。
600 :
デフォルトの名無しさん :2008/03/09(日) 11:39:46
頭がこんがらがってきたのですが、 クラスmyclassの大きさをnバイトとして、次のように定義すると、 myclass *A; A = new myclass[x]; myclass B[x]; sizeof()の戻り値が n ← sizeof(myclass),sizeof(*A),sizeof(*B) 4 ← sizeof(A) x*n ← sizeof(B) となるわけですが、AとBにはどういう違いがあるんでしょうか
配列とポインタの違い。 ちなみにsizeof (*B)は、Bが配列型→ポインタ型への変換を受けた後、 それに単項*演算子を適用しているので、B型のインスタンスをsizeofにかけていることになる。
Aはポインタ型(配列の先頭を指す) Bは配列型(値は配列の先頭を指すポインタ) ってことでしょうか 両方A[0].xとかB[1].xでクラスのメンバ変数xにアクセスできるので、 イマイチ区別が付きませんでした
cout << Bでどう考えてもBがポインタだったのは、 自動で変換されていたためでしたか そのページを参考に基本的な部分を整理しようと思います ありがとうございました
605 :
デフォルトの名無しさん :2008/03/09(日) 17:48:09
これの直しかたわかりませんか? コンパイル時にアットマークがついてしまいます Error 42: Symbol Undefined _WSACleanup@0
それはstdcall関数の仕様。 @がどうとか関係ないから、ws2_32.libか何かをリンクしろ。
C++の入門書のお勧めは?
accelerated C++
>>611 評判はとてもいいのですが
入門向きでは無いだろあれw
C++が初めてで、他になにかやってたってとかならまだいいんだろうけど
>>611 読む価値は非常に高い良書。
ただ入門書を探してる人のレベルによっては
難しいと感じるかもしれないというだけのこと。
いずれ読むべきだから買っておけ。
JavaやC#でいうところのInterface的なものを真似る場合 class IHogeの中に実装があってもいいのでしょうか?
実装があるならabstractクラスを真似るべきじゃね
多重継承最強!
>>614 「真似る」のなら駄目
C++的にIHogeの中に実装があってもいいかどうかは別ね
accelerated c++ はベターCでなく C++ らしいやり方で進めてるところが好き
いずれ読むべきという点で「C++の設計と進化」をお勧(ry
独習C++やらロベールやら色々あるから 本屋でとりあえず立ち読みでもしてみれ。 ネットでポチっと買うと合わなかった時悲惨。
現行規格とはずれているがARMの内容は秀逸。
じゃあ一発 これならわかるC++ ブルーバックス版
猫でもを妙に推している人がいるな。 本人なのか、信者なのか。
猫でもわかるシリーズにC++編はないわけだが
ググったら確かに。書籍化されてるのは C だけだな。 じゃあ本人ではないなw
webにはちょっとあるけど全然使えない
629 :
622 :2008/03/10(月) 00:13:06
>>625 推してるの一人じゃね?
俺はwebでも見れるよって言いたかったの。
"だけだな"って言ったのはacceleratedとかD&Eとか無茶やろって思ったからw
独習やロベールは別に無茶じゃないだろ?
>>625 猫は素人でも知ってる場合があったぞw
素人メールに猫の話があった時には目を疑った。
Web主体の素人さんにはPG的に一番名度高いのかも知れんね。
>>631 ごめん"立ち読みしてみれ"のあたりしか読んでなかった。
独習は良いかもね。
猫でもはサンプル動かして改造するのには最適 入門書読んで、猫でもで遊んで、オブジェクト指向とか良いプログラミング作法でも学んでいけばいいんじゃね
C言語を独学で学んでいるのですがよく分からない文字(演算子?)があります -> ↑これはどういった意味の物なのでしょうか?
アロー演算子
>>635 A* a = new A();
//以下の2行は同じ
(*a).aaa();
a->aaa();
>>635 ポインタptrが指す構造体のメンバmemである
(*ptr).mem を ->演算子を用いて
ptr->memと表す。
a -> b は、aが指す構造体のメンバbを表す。
俺は (*a) も a-> も導入せずに、
同じ意味で a@ みたいな演算子が欲しかったよ・・・
[0]の構文糖衣として。
[email protected] ();
a@ += 10;
a@++;
まぁ、提案するとしても20年くらい言うのが遅い(C言語宛てになるし)わけだけど。
Delphiみたいに ^ がいいな
そうなると、定義もDelphiっぽくA^ a;になってC++/CLI設計者が涙目w
A$でおk
>>640 そもそも*(ついでに&も)が後置だったら良かったと俺は思う。
なんで前置にしたんだろう。
それを言い出すとなんで関数ポインタの宣言はあんなに狂ってるんだとかそういうハナシに
そもそもなんでこんな話題話してんだという話になる
何故前置にしたのか気になってD&Eちょっと見て C言語の設計者の方じゃないと意味無いことに気付いた
素人の友達にWindowsプログラミングしてみたいから いい本ないかと聞かれて猫でもわかる〜を薦めたら 馬鹿にするなと怒られた。 他意はなかったんだが、うかつだったわ。
それだけ聞くと、なんか馬鹿っぽい友達だな。
数学でも単項演算子は前置である割合が多いから、 特別な理由をその時思いつかなければ まず後置にはしないと思う。
オブジェクトの排他制御というのはマルチスレッドで処理するとき以外は気にしなくて良いのでしょうか? というか、マルチスレッドを利用する場面というのはどういうときなのでしょうか
マルチスレッドでぐぐれよもう
654 :
デフォルトの名無しさん :2008/03/10(月) 11:21:28
>>652 GUIアプリなんかで通常の機能を提供しながら重い処理をバックグラウンドでやるとか
>>649 猫でもわかる〜のサイトは、中身はいいけど、体裁がなぁ...
プログラムの入門サイトなんだし、HTMLのタグぐらい、もうちょっと調べようよつとか思うよね...
文章が読めたら何でもいいだろ・・・
本人乙
むしろプレーンテキストでいい
661 :
デフォルトの名無しさん :2008/03/10(月) 13:33:18
Delphiなんかの ExpandFileName関数(相対パスを絶対パスにする)と 同じ働きをする関数って VC++ だとなんて関数?
GetModuleFileNameでがんばるとか
VC++標準じゃないが、boostにパス変換がある。 boost::filesystem::system_complete
>>662 何故GetModuleFileName()?
あれはカレントからの相対パスを解決する関数なんだから、モジュールからの相対パスにしちゃダメだろう。
GetFullPathNameは駄目なの?
666 :
デフォルトの名無しさん :2008/03/10(月) 13:56:31
クラスのメソッドから、クラスのインスタンスの変数名を知る方法ってありますか? 具体的には、 class test {}; test a1; a1.method(); としたとき、method内でa1という名前をしることは出来ますか?
面倒だがコンストラクタの引数で変数名を文字列受け取るようにして 自分で保持するってのは? class test { std::strung instance_name; public: test(const char *pName) { instance_name = pName; } } test a1("a1");
変数名が知りたいっていう状況がわからんのだが どう使うの?
671 :
デフォルトの名無しさん :2008/03/10(月) 14:26:04
>>667-670 ありがとうございます。
用途はデバッグです。あるクラスの中身を表示させているのですが、
どのインスタンスかがわかりやすいようにしたかったので、、
自動化したいので、コンストラクタの引数に書くのは避けたいです。
が、これが一番確実ですかね。
>>671 Use the debugger, >671
デバッグ用途ならマクロの文字列化演算子 # を使うとか
>>671 何らかの制限で、デバッガが使えない場合
デバッグログが使えるのならば、
生成した側が、確保されたアドレスを出力(__FILE__と、__LINE__も一緒に出力するとわかりやすい)
クラスの中身を表示するところでthisを表示すればいいんじゃないかな?
>>674 なかなか面白い書き込み時間だ
676 :
デフォルトの名無しさん :2008/03/10(月) 16:52:05
679 :
デフォルトの名無しさん :2008/03/10(月) 19:01:42
ハ,,ハ ('(゚∀゚∩_ おいらをどこかのスレに送って! /ヽ 〈/\ お別れの時にはお土産を持たせてね! /| ̄ ̄ ̄|.\/ |dexiosu|/  ̄ ̄ ̄ 現在の所持品:たばこ・ライター・コーヒー・ブラックブラック・枕・ケータイ電話 睡眠薬・聖教新聞 ・ダッチワイフ・外付けSCSI340MHDD・ネットランナー4月号 TYG02・小嶋進社長・ペプシNEX・モツ煮・ヌルポ・伊予柑・寒いギャグ ・7年ものキムチ ・カビキラーストロング ・ハイスクール奇面組文庫版全13巻 ・(元)関内太郎 ・チャッカマン ・ぺヤングソースやきそば・魔法先生ネギま!14巻限定版 ・小田急3000形・PSP ・デスノート ・ファブリーズ ・ポーション ・SH902i ・Windows3.1
>>676 生ソケットでHTTPをやるプログラム例はウェブにやまほど転がってるか
ら、それらを見て何が足りないか調べてみましょ。
gethostbyname()やsocket()のエラーチェックもしましょ。
それ以外にもツッコミ所が多いけど致命的じゃないので省略。
681 :
676 :2008/03/10(月) 20:26:39
うん、何か知らないけど分かって言ってるのか分かってないのかようわからん、 役に立たない情報ありがとう。
>>680 例えばnewしてdeleteしないのは、それが習慣化すると致命的だと思うぞ。
>>676 ということで、>678。
まさかとは思うが、そのレベルで外部に直接繋ぎに行くなよ。
接続先に迷惑掛けることになるからな。
683 :
676 :2008/03/10(月) 20:44:42
>>682 いまどきのパソコンは自動で解放するから別にデリートしなくていいし
(つーかdeleteしなかったのはこの程度のプログラムだったらいらんし面倒くさいからで)、
その機能的な面を考えておるんだったら、最初っから一気にメモリ確保しといて、
解放しますよ。あと、ポート80に設定してないとか言われてたが、
あれはポート80に設定しなかったら自動で80に設定してくれるからで、面倒くさいから。
socket()のエラーチェックしなかったのは、面倒くさかったからで。
>>682 newしてdeleteしない習慣がついてます、サーセンwww。
vectorとかshared_ptrがないと生きていけません。
お前に教えるのが面倒くさいわ。
きみのところの石がPowerPCとかMIPSとかでないなら、 iprt.sin_port=80; は iprt.sin_port=20480; にするといいお
687 :
676 :2008/03/10(月) 20:50:38
>>684 俺もC++で、ついこないだまで必死でc_str( )使ってた。
688 :
デフォルトの名無しさん :2008/03/10(月) 20:52:26
newはクラス以外で使うなよ STLのように自動開放する以外には使うべきでない
689 :
676 :2008/03/10(月) 20:53:06
>>686 あぁ消したハズなのに普通に代入してたの残ってた。
このことか。ありがとう。
てか20480って怪しいポート何?
deleteめんどくさいならnewしなきゃいいって発想はないのかなぁ。 悪くてもこの場合固定長配列でいいし、もっと言えばstringを使うべきところ。 全く意味のないnewじゃん。 newしてdeleteしないのが致命的にならないのはこのサイズのバイナリだからであって、 自動でやるからデリートしなくて良いって考え方は非常に危険。くせにするなって言う意見のがもっとも。 たとえば、photoshopみたいなソフトを作ってる人がnewしてdeleteしなかったらどうなるか。
はい、GCを導入します
692 :
676 :2008/03/10(月) 20:59:43
>>690 ありがとう。今度からできるだけ意味無いことは止める。
string型にすればいいだろうなぁとは思ってた。
最初mallocにしてたけど、知らん間にnewになった。
そもそもstringならnewはいらんはなしだったけど、そこまで頭回らんかった。
俺の脳裏にはC言語っぽいのをできるだけC++っぽくしようってのがあったんだと思う。
かえってそれが変に見えたのは認める。
勉強になりました。
つーか、 ・getaddrinfo使えタコが ・面倒だからとエラー処理サボると、もっと面倒な事態に の例
694 :
676 :2008/03/10(月) 21:07:27
>>693 ネットワーク系に触るの生まれて初めてなのよn
getaddrinfoか、メモメモ
/ ̄ ̄\/)
f ヾ
| ⊂(゚Д゚)|
ヽ _(◎)ノ ノつ
/ノ/ ハヽ二二ノ
( (||i) )ヽ\
ヽ)L人(_/(ノ`J
696 :
676 :2008/03/10(月) 21:42:16
>>695 NEってCCNAとかのイメージが先行して配線を弄ってるイメージ強かったけど、
プログラム組ませると「間違えると危険なんだなぁ」とは思った。勉強になりました。
安全な下級PGに戻ります。
スレがカオス気味でワロタ
ここでド素人の俺が颯爽と質問 int型へのポインタの宣言って int *a; int* a; この二つで差がありますか?
int* a, b;
若干スレ違い臭いのですが、質問させてください。 コンパイル時、2つのコンパイルオプションを指定したいのですが、どのように書けばいいのでしょうか。 例えば`wx-config --cppflags` と `pkg-config --cflags gtk+-2.0` を同時に使いたいのです。
>>698 違いはありません。
しかし、その二つはまれに戦争の火種となります。
>>698 int *a, b;
int* a, b;
>>699 ,701-702
ありがとうございます
intだとint型とint型へのポインタが同時に宣言でき、
int*だとint型へのポインタのみ宣言できるわけですか
>戦争の火種
(((( ;゚Д゚))))ガクガクブルブル
>703 戦争の火種って言っても空襲は来ないから安心しておじいちゃん。
int *a, b; int* a, b; 二つとも aがint型へのポインタ。int型の変数bでしょうか?
Yes. int* a, b; と書こうが、b はポインタにはならない。
int * a; のように書く人もいるね。
>>700 単に並べればいいよ。
gcc `wx-config --cppflags` `pkg-config --cflags gtk+-2.0` mycode.cc
int*a; 派
おまえがどう書こうが関係ねえ
int * a ; 派
716 :
700 :2008/03/11(火) 00:17:01
717 :
デフォルトの名無しさん :2008/03/11(火) 00:34:27
i\ n\ t * a ; 派
boost::mpl::identity<int*>::type a;派
719 :
デフォルトの名無しさん :2008/03/11(火) 01:21:53
string の読み込みがないのが不便ですね 改行やバリナリはありますが 自作するしかないですか
720 :
デフォルトの名無しさん :2008/03/11(火) 01:24:21
C言語やWindowsAPIはファイルの入出力が低レベルのしか無いです たとえば空きメモリを調べてバッファを使って出力するとか そういうのを強化するライブラリ無いですか ビット単位の出力もないです
boostでおk
722 :
デフォルトの名無しさん :2008/03/11(火) 01:27:40
詳しく教えてください ライブラリ名とか
723 :
デフォルトの名無しさん :2008/03/11(火) 01:32:21
例えば、Fstream というバッファ付きファイル出力クラスを自作したとします 書き込みがあまりなくなったらメモリを解放したいのですが、 一番最後の書き込み時に解放しなかった場合、 それ以降アクセスがなかったら無いことを知ってメモリ解放するにはどうしたらいいですか
デストラクタで開放するようにして、スマートポインタに入れるなりなんなり
725 :
デフォルトの名無しさん :2008/03/11(火) 01:34:41
クラス生成時にサブスレッドを動かして 時間計測してシグナル出せば良さそうですね
726 :
デフォルトの名無しさん :2008/03/11(火) 01:37:56
>>724 複数のファイルを同時に扱いたいです 1000個の書き込みがあれば
一つあたり100KB確保でも大きいです
単独でバッファ管理するより複数を調べた方が良さそうですが
727 :
デフォルトの名無しさん :2008/03/11(火) 01:43:50
例えば Fstream fp("out1"), fq("out2"); としたとします クラスはfpの状態とfqの状態両方を知ることは出来ますか
static変数ででも管理すればいいだろ
729 :
デフォルトの名無しさん :2008/03/11(火) 01:57:24
fp[100]としたとき、メモリを解放した方が良い番号がわかったとき自動的に 解放させるにはどうしたらいいですか? 最近参照された時間を保持していてもメンバ関数からでは 他のメンバ変数はわからないですよね
731 :
デフォルトの名無しさん :2008/03/11(火) 01:59:49
staticは共用されないですか? 個別の時間を保持しないと駄目ですが
全インスタンスの個別の時間を保持するlistかmapかなんかをstatic変数にすればいいだろう
だいたい貴様の知識が乏しいのは自分でもわかってるんだろ。 その貧相な知識で勝手に判断して人のレスを無視するんじゃねえよ
734 :
デフォルトの名無しさん :2008/03/11(火) 02:03:54
時間管理もバッファも、vector型にして共用すれば良いですか?
735 :
デフォルトの名無しさん :2008/03/11(火) 02:09:53
あとメモリ解放のためにサブスレッドを動かしたいのですが コンストラクタに入れるとクラス生成ごとに呼びだれると思うのですが これも共用するにはどうすればいいですか? static fnc(){}などと書けば初めの一回だけになりますか
質問する前に手を動かしてみたら?
闇雲に手を動かすだけで、「〜をやってみましたがうまくいきませんでした。なぜですか。」とか聞いてきそうだ。 >static fnc(){}などと書けば初めの一回だけになりますか staticというキーワードを知っているのなら、それについての最低限の仕様くらいは 自分で調べたほうがいいよ。webを見るなり、まともな入門書を読むなりして。 凝ったことをやろうとする前に、もっと先に学ぶべきことが多そうだ。
738 :
デフォルトの名無しさん :2008/03/11(火) 02:28:02
うごかないですが原因がわかりません どうすればいいですか class cls{ public: static int n; cls(){ n=0; } }; main(){ cls x; }
どううごかないんだ コンパイルエラーなのか 画面に何も表示されないのか 後者なら別におかしくないぞ
740 :
デフォルトの名無しさん :2008/03/11(火) 02:37:50
Error: 未解決の外部参照 'cls::n' がTEST.OBJ から参照されました とでます
static変数の定義がないから static int cls::n;
742 :
デフォルトの名無しさん :2008/03/11(火) 02:42:55
それは知りませんでした サンクス あとクラスのメンバ関数も共用出来ますか? 初めに一度コンストラクタで起動するだけにしたいです
>>742 staticをメンバ 関数につけたらどうなるか調べなおせ
744 :
デフォルトの名無しさん :2008/03/11(火) 02:56:22
他人のコードを読んでいて、 namespace std { template <> void swap(hoge &a) みたいな記述があったのですが、templateのあとの<>の中が空白でも コンパイル出来ているのですが、なんででしょうか?
パラメータ0個のテンプレート
746 :
デフォルトの名無しさん :2008/03/11(火) 03:01:30
>>745 ありがとうございます。でも意味がないような、、、
どんな時につかうのですか?
特殊化でぐぐれ
748 :
デフォルトの名無しさん :2008/03/11(火) 03:11:47
read(fp, x) write(fq,x) としたとき、読み込むファイルが1G以上だとメモリがたらなくなります あらかじめ書き込むサイズが判明していたとしてマルチスレッド化して read(fp, x) write(fq, x, N, KAIHOUFLG) としてメモリを解放しながら読み書きするにはどのように実装すればいいですか
マルチスレッドに何の関係があるんだよ。 分割して読み書きすればいいだけだろうが
750 :
デフォルトの名無しさん :2008/03/11(火) 03:17:02
read(fp, x)はファイルを読み込みますが、例えば1G読み切るまで停止しないって事です
それはそのreadの設計が悪いだけだろうが。
752 :
デフォルトの名無しさん :2008/03/11(火) 03:20:49
>>747 ありがとうです。特殊化でぐぐったら、wikipediaのエントリが先頭に出てきて、それを
読んだらわかりました。(わかりやすく書いてあった)
templateのうち、コンパイラまかせじゃなくて自分で書いてしまいたいところを自分で
書くということですね。
753 :
デフォルトの名無しさん :2008/03/11(火) 03:21:11
1Gのファイルを読み込んだとして、 メモリを解放しながら書き込むという指定をすると 読み込まれた部分に対して先頭からメモリを解放しながら書き込みます
754 :
デフォルトの名無しさん :2008/03/11(火) 03:23:27
通常使用では一括して読み込むことも出来るし、 メモリを解放させながら読み込むことも出来るという汎用の関数を作りたいんです
なら作ってください
756 :
デフォルトの名無しさん :2008/03/11(火) 03:26:09
やり方を教えてください
上で散々でてるがな。
758 :
デフォルトの名無しさん :2008/03/11(火) 03:30:20
商品先物や、為替取引と同じようなものです 現物を扱わずに売り買いだけを先にしてしまうようなものです 読み込みと書き込みの約束だけをしてしまい不要ならメモリを解放します
口約束で終わるって事か?
スレが伸びてると思ったら、梯子もなしに屋上に上ろうとする馬鹿が沸いてたか。
VirtualAllocでCOMMITを調整する話か? まー、32bitアプリは仮想メモリ空間も 2Gあたりでリミットだからあんまし意味がないけど
762 :
デフォルトの名無しさん :2008/03/11(火) 07:20:53
763 :
デフォルトの名無しさん :2008/03/11(火) 07:23:38
>>756 Windowsなら4つのAPIで実現できる。
APIの頭文字はそれぞれ、C、M、U、Cだ。
764 :
デフォルトの名無しさん :2008/03/11(火) 09:38:41
書き込み予約と、読み取り予約と、バッファ管理して それらを同時に動かして快適動作させたいわけです コードを教えてもらえませんか? 読み書きのバッファを128KB単位にして管理すれば良さそうなんですが・・ x[n]のようにデータにアクセスできるが、前方が解放されていたとしてもそれ以外は同じアクセスが出来るようにしたいです
766 :
デフォルトの名無しさん :2008/03/11(火) 10:36:58
>>764 したい事は
>>748 なのか?
もしそうなら、標準関数は何もしなくてもそうなってる
一体何のために何がしたい?
読み込みや書き込みをできる限りメモリにキャッシュしたい、というこ となら、組み込み環境でない限り、OSがそれぐらいはやっている。
そんなこと無いよ それだったらFFCやfast copyがOS標準のコピーを上回らないはずだよ 一つの巨大ファイルだけを扱うならば、速度差は出ないだろうけど 複数のファイル(1000以上同時など)を扱うと標準のはやつにたたない あと2Kずつ書き込みがあったとしたらそのつどAPIでそのまま書き込んでいたらとても鈍いよ
ファイルをメモリにロードする事、複数の少数ずつのファイル出力の最適化する事 上のファイルロードをスレッド化して読み込み中に不要なメモリを解放出来るようにすること
まずC言語とWindows APIのファイル入出力は難しいんだよ Read( "inputfile", buf ); Write( "outputfile" , buf ); だけで扱えるようにしたい しかしここで、バッファ管理やマルチスレッド化を導入しなければ 巨大ファイルを読み込むときにメモリ不足が足らなくなったり、少数ファイルの書き込みで速度低下する これらを解消して簡単なファイル入出力をしたい
ファイルマッピングをmemcpyしたまえ 64ビットならアドレス空間も余裕だ
>>769 FFCとかはFILE_FLAG_NO_BUFFERINGをつかって
システムキャッシュにのせないことで高速化してるんじゃなかったっけ?
>>770 目指している方向はわからなくもないが、
ここで色々訊いているような人間が使い物になるものを作れるかどうか不安。
何事も、下手な自作よりOS標準など既存のものほうがずっとうまいと仮定すべき。
読むだけじゃ意味無い(処理するために読む)んだから、 巨大データをオンメモリでっていうこと自体に元々限界があるの。 分けなさい。
すみません 出力値が異なるのですが原因がわかりません なぜでしょうか? #include <iostream> #include <string> using namespace std; #define N 10000000 int main(){ unsigned int n,m,cn[256]; string x(N,'\0'); for(n=0;n<N;n++)x[n]=rand()&255; for(n=0;n<256;n++){cn[n]=0;for(m=0;m<8;m++)cn[n]+=(n>>m)&1;} unsigned int sum=0; for(n=0;n<N;n++)sum+=cn[x[n]]; cout<<sum<<endl; #define b(x,i) ((x>>i)&1) sum=0; for(n=0;n<N;n++){ int y=x[n]; sum+=b(y,0)+b(y,1)+b(y,2)+b(y,3)+b(y,4)+b(y,5)+b(y,6)+b(y,7); } cout<<sum<<endl; }
自己解決しました string x(N,'\0'); → vector<unsigned char> x(N,0); で一致しました
ちょっとお尋ねしたいのですが コンパイル時 ../source/memo.h:15: note: candidates are: MyFrame::MyFrame() ../source/memo.h:15: note: MyFrame::MyFrame(const MyFrame&) のようなエラーが出たのですが、このエラーはどういう意味のエラーなのでしょうか??
それ単独では出ないと思うけど・・・ その直前のエラーについての補足説明で、 候補としてこういう関数がありますよってことじゃないかなたぶん?
山ほどあるコンパイラのエラー出力フォーマットなんていちいち覚えてられないよ。 コンパイラ・ソース・エラー(省略せずに)を明記してくれ。
>>778 noteって単語と、candidateって単語の意味くらい調べましょうね。
そうすればそれらの行がエラーじゃないことと、何を言わんとしているか位判るだろうから。
>>769 >複数のファイル(1000以上同時など)を扱うと標準のはやつにたたない
 ̄ ̄
>巨大ファイルを読み込むときにメモリ不足が足らなくなったり、少数ファイルの書き込みで速度低下する
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
落ち着いて、日本語で書いてください。
int a[6]={0,1,2,3,4,5,6} とすると、配列の中身を一気に定められますが、 int a[6] と一度定義した配列に一気に中身を代入することは可能でしょうか
>>783 int oneShotArray[] = {0, 1, 2, 3, 4, 5, 6};
int a[6];
std::copy(oneShotArray, oneShotArray + 6, a);
memcpy(a, oneShotArray, sizeof(* a) * 6);
誘導されてこちらに来ました。 ifstreamで半角空白を含むファイル名や、日本語を含むパスで ifstream ifile(フルパス名);で失敗してしまうのですが、これは仕様なのでしょうか? 仕様なのでしたら回避策はあるのでしょうか? Visual Studio 2005SP1を使用しています。 よろしくおねがいします。
コンパイルはVisualStudio2005 Command Promptで行いました。 フルパス名をコピペして、\を一つ減らしてエクスプローラーに貼り付けると正常に開けます。 #include <iostream> #include <fstream> #include <windows.h> using namespace std; int main(int argc, char **argv) { ifstream ifile("d:\\新規テキスト ドキュメント.txt"); if(ifile) { MessageBox(NULL, "success", "info", MB_OK); ifile.close(); } else { MessageBox(NULL, "failed", "info", MB_OK); } return 0; }
>>786 向こうの誘導したレスの前半は無視ですか?
えくすぽろーらで開けんだから、ファイルはあるんしょ
とりあえずtest.txtで試してみたら?
だから、カレントディレクトリはどこなのかとw
ソースコードのエンコーディングがutf8なんじゃない?
>>787 ファイルはあります。
>>789 "d:\\test.txt"ではsuccessとなります。
だったらロケール設定して見るんだ。
>>791 ソースコードに
// あいうえお
と入力して、テキストエディタでエンコードを確認しましたがシフトJISでした。
>>793 setlocale(LC_ALL, "");
で出来ました!
ありがとうございました!
向こうで速攻でロケールについて指摘されているのを無視するからだ・・・
なんで無知の身でもらった回答を勝手に「選別」するんだろうな。
798 :
デフォルトの名無しさん :2008/03/11(火) 23:17:43
自分クラスのアドレス(実際はthis)をstatic_castで上位クラスにキャストしなおして、上位クラスのメソッドを呼ぼうと思ったのですが segmentation faultになります。 baseclass::method(); と書いて目的は達成できたのですが、segmentation faultになる理由が分かりません。 #あと、このスレのタイトルが #【初心者歓迎】C/C++室 Ver.50【環境依存OK】 # ってなってるけど、なんか何度かVer.50がくりかえされているような気がするのは自分だけ?
だからコードを晒せと。スラッシングが起きてるんじゃねーだろーなー
800 :
デフォルトの名無しさん :2008/03/11(火) 23:51:29
どこで聞けば良いのかわからなかったので、 環境依存OKということでここでお伺いします。 linuxThreadsでは、あるスレッドでsetpriority()を呼ぶと 親スレッドの優先度は変化しないと思いますが、 NPTLでは同一のPIDならすべて変化するのでしょうか?
>linuxThreadsでは、あるスレッドでsetpriority()を呼ぶと >親スレッドの優先度は変化しないと思いますが、 そうは思えないが。
802 :
778 :2008/03/11(火) 23:54:27
レスくださった方々ありがとうございます。 noteはなんとなく分かったのですが、candidatesは調べてもわかりませんでした。 candidatesは何のことなんでしょうか・・。 どなたかご教示頂けると幸いです。
ヒント:複数形
804 :
デフォルトの名無しさん :2008/03/11(火) 23:57:11
>>799 すいません。
class base {
public:
virtual void resize(){}
};
class deri : public base {
public:
virtual void resize() {
#if 1
base* tmp = this;
tmp->resize(); // ここでseg fault
#else
base::resize(); // 問題なし
#endif
}
};
です。
>>804 無限再帰でスタックオーバーフローだな。
・base::resize() 静的に呼ぶ ・tmp->resize() 結局virtualたどってderi::resize()にくるから無限再帰
807 :
デフォルトの名無しさん :2008/03/12(水) 00:00:30
>>801 即レスどうもです!!
そうなんですか?
manにはプロセスの優先度を設定すると書かれてありました。
linuxThreadsはPIDを共有しないので変化しないと思ってたのですが。
PIDは違うけどプロセスは同一ということでしょうか?
808 :
デフォルトの名無しさん :2008/03/12(水) 00:07:58
>>805-806 ありがとうございます。tmp->resize()の前にログをいれて再帰していることを確認しました。
再帰というのは全然考えてなかったです。
助かりました。
>>802 ../source/memo.h:15: note: candidates are: MyFrame::MyFrame()
../source/memo.h:15: note: MyFrame::MyFrame(const MyFrame&)
俺も英語は苦手だがせっかくネット使えるんだから有効活用しようぜ。
「MyFrameが複数の候補がある」という内容。
コード上でどちらの処理を使うかがコンパイラに判断できないからだ。
エスパーすると、直前に no matching function for call to 〜 とか云われたはず。コードで書いてある引数に マッチする関数の宣言がなかったって話。
811 :
778 :2008/03/12(水) 01:14:43
>>803 さん 809さん 810さん
レスありがとうございます。
なるほど、普通に「候補」でよかったんですね。
なんかプログラミングの専門用語でcandidatってのがあるのかと勘違いしてました。
ありがとうございましたm(_ _)m
812 :
デフォルトの名無しさん :2008/03/12(水) 01:16:15
正常なSJISならば出現しない番号0-255ってありますか?
>>812 日本語でおkと言いたいが、
windowsなら スタート → すべてのプログラム → アクセサリ → システムツール → 文字コード表
を見てみては?
814 :
デフォルトの名無しさん :2008/03/12(水) 02:02:04
すみません 番号を教えてください
815 :
デフォルトの名無しさん :2008/03/12(水) 02:10:10
新聞、2ちゃんなどを1ギガほど計測したところ次の通りでした 下位のものは間違ったSJISの番号でしょうか? 26番15475回 30番17423回 22番18440回 127番18931回 25番19273回 上位 32番45338056回 130番93045087回
スレ違い
一度定義したクラスのデータメンバやメンバ関数をあとで追加することってできないのでしょうか? 例えば、40行目で clsss aaa { public: void sample1 (); } と定義したクラスのデータメンバとメンバ関数を、 80行目で class aaa { public: int xxx; void sample2(); } みたいな感じで、追加する感じです。 上のように書いたのをコンパイルしようとしたらエラーが出たのですが、 すでに定義したクラスの機能を拡張するにはやはり継承しなければいけないのでしょうか??
はい、そうです
>>817 40行目の定義を削除すればいいじゃん。
環境はLinux/Windowsの両方です HDD残量を取得したいのですがどのようにすればよいのでしょうか? 環境に関係なくとる方法はあるのでしょうか? もしなければ,どのようにして取得すればよいか教えていただきたいです.
821 :
デフォルトの名無しさん :2008/03/12(水) 06:16:19
環境別に分ける
>>811 だから、英単語の意味を調べたら単に「候補」って出てくると思うのだが……
>>820 そもそも、どのディスクの残量を知りたいのかね。
825 :
817 :2008/03/12(水) 11:28:26
>>818 さん
>>819 さん
レスありがとうございます。
40行目のやつは、実際今作ってるプログラムだとincludeで読み込んでるライブラリで定義していまして、
消して下で書き直すのもライブラリ自体をいじるのもなんか好ましくないような気がしまして。
やはり継承するしかなさそうですね。というかむしろライブラリのクラスは継承してから使うものなんですかね。
ありがとうございましたm(_ _)m
826 :
デフォルトの名無しさん :2008/03/12(水) 13:36:09
すれ違いといううことでここに移ってきたんですが、 stlの使い方について質問です。今リストの中に1,2,4,8,16,32,64 と入っているんですが、"erase" を使って5番目の数字を削除して中身を表示し、 その後に3番目の数字を削除して表示。 そして、"insert"を使って3番目と4番目の 数字の間に7を入れて表示という感じにするにはどうしたらいいんですか? osはubuntuでg++を使っています。 #include <iostream> #include <iterator> #include <list> using namespace std; int main(){ list<int> mylist; for(int i=1; i<=64; i *= 2) mylist.push_back(i); cout<<endl; list<int>::const_iterator itr1; for(itr1 = mylist.begin(); itr1 != mylist.end(); itr1++) cout<< *(itr1)<<" "; return 0; }
質問です 引数つきコンストラクタから、デフォルトのコンストラクタを呼ぶことはできないでしょうか? Javaではできたので、C++でもできないものかと思っているのですが CHoge::CHoge() { // 共通の初期化がだらだらと } CHoge::CHoge(int type) { // CHoge()で共通の初期化を呼び出したあと、色々やりたい } CHoge::CHoge(const char *psz) { // CHoge()で共通の初期化を呼び出したあと、色々やりたい }
初期化処理をまとめたプライベート関数を作ればよろし
>>827 ないよ。
そんなことできたら初期化子が重複するから。
>>826 >"erase" を使って5番目の数字を削除して中身を表示し
削除したら表示できないだろ。
削除するだけでいいなら、文字通りerase()を使えばいい。
# erase(), insert()は引き数にiteratorを必要とするが、
# advance()を使えば何番目を指すiteratorを作れる。
>>827 C++でもコンストラクタからコンストラクタを呼び出すことは文法違反ではない。
CHoge::CHoge()
{
// 共通の初期化がだらだらと
}
CHoge::CHoge(int type)
{
CHoge(); //一時オブジェクトの生成!!!!!
//いろいろな固有の処理
}
しかし、こんなコードを書いたならば想像してるとおりにはならないだろう。
こういう場合C++では、共通化したい処理をまとめた
(恐らくはprivateな)メンバー関数を別に用意する。
void CHoge::init();
CHoge::CHoge(int type)
{
init(); //共通の処理
//いろいろな固有の処理
}
勇気を出して変えてごらん HogeをMoeに変えてごらん そうすれば世界も変わって見えるんだ
834 :
デフォルトの名無しさん :2008/03/12(水) 14:20:50
>>831 "erase" を使って5番目の数字を削除して中身を表示 1,2,8,32,64 その後に3番目の数字を削除して表示 1,2,32,64 そして、"insert"を使って3番目と4番目の数字の間に7を入れて表示 1,2,32,7,64 というう感じにしたかったんです。
>>834 >831に書いた内容の何が気に入らないんだ?(:;
つーか、4はどこに消えたんだ?
マクロでクラス生成をしたいのですが、任意のクラス名を受け取る方法はないですか? #define GENERATE_CLASS class X {...} // マクロを呼び出す側からXの部分を任意に指定できるようにしたい
#define GENERATE_CLASS(x) class x{hogehoge ではないの?
template使えば?
840 :
837 :2008/03/12(水) 15:58:32
>>838 その方法はGENERATE_CLASS(Hoge)と使った時、Hogeの部分でエラーが出た気がしたのですが、
今もう一度試してみたらできました。(別の部分で間違いがあったようです)
簡単すぎること聞いて申し訳ないです。
>>839 template引数のバインドができない関係で、マクロでクラスを書くことになってので、templateでは無理なのです。
>>840 まさかとは思うが、業務上のプログラムを2ちゃんで質問しながら書くなよ。
842 :
837 :2008/03/12(水) 16:06:27
Visual C++ 6.0の課題で分からないところがあるので助言お願いします。 「main関数において、返却値の値によって表示の方法を変えよ」 とあるのですが“表示の方法を変える”とはどのようなことをすれば良いのでしょうか? 返却値は1、2、3の三つです。
printf("%dがきたー\n", henkyakuchi)
変化球がきたに見えた
>>844 ありがとうございます
とりあえずその方向でやってみます
>>843 もし問題文が
「main関数において、返却値の値によって表示の方法を変えよ」
だけなら、回答はこうだ
「日本語でおk」
うむ、出題の意味がわからん。 そして宿題は宿題スレへ。
こういうことか! switch(henkyakuchi) { case 1: printf("きたー"); break; case 2: puts("きたー"); break; case 3: cout << "きたー"; break; }
>>843 switch (henkyakuti) {
case 1:
printf("0"); break;
case 2:
fputs("0", stdout); break;
case 3:
putchar('0'); break;
}
851 :
850 :2008/03/12(水) 18:18:48
ネタかぶったorz
全文載せないでまともなヒントあげれると思ってんの? 載せるなら宿題スレ池だが
>>843 の文章だけでは題意が読み取れない
これが分かっただけでもいいんじゃないか?
っつーか問題の意図は出題者に聞けよ
>>852 問題文を他人に意味が伝わるように要約できない=テメーが問題文の意味を理解していない
>>856 理解できてないから質問してるんじゃないか?
理解できてないなら要約すべきではないわけで
>>852 みてイラっときた俺はたぶん短気なんだろう
まとめると、質問するなら要約するなってことだな
ある変数の値に応じて特定の処理をさせたいのですが、 値のパターンがかなり多い場合、 switch〜case文とif〜elseif文ではどっちのほうが処理が早いでしょうか ひとつの値に対しひとつの処理なので、どちらの文を使っても同じように処理できます (switch〜caseの場合はbreakで抜けるので) あんまり多い場合、関数の配列でも用いた方がいいのかもしれませんが……
試せるなら実測しろ 試せないならどっちを使っても一緒。気にするだけ無駄。
switch 文にはジャンプテーブル最適化というのがあってだな、 その最適化が効けば case ラベルの位置のアドレスの表を使ってジャンプするようになる。
しかし分岐予測の効き方を考えるとジャンプテーブルの方が遅い場合もある 実測して比べるしかない
多くの場合においてある1つの条件に集中するような場合は それだけ if して、その他を switch にするとか?
>>860 一般的にはswtichが効率的。
なぜならswitchはジャンプテーブルなり、各個比較なり、
コンパイラが最適なものを選択すると期待できるから。
>>857 問題が理解できないのなら、問題の意味を教えてくれと問うべきだし、
問題が理解できているのなら、その解決策に関して問うべきだし、
解決策があるていど目星が付いてるが、ひっかかる所があるならば、その点を問うべきだろ。
自分が理解できない問題を一部だけ示して教えろなんて、どんなバカだ。
処理を後々追加する羽目になる可能性があればswitchの一択でしょ。
顔真っ赤なやつがいるな いいかげんその話題は終われ
上と似たようなどうでもいい質問なんだけど bool z = a() && b() && c() && d() && e(); みたいな文があったとき、a()から順に、最悪e()まで調べていくと思う。(&&演算子は必ず左から調べるよね ということは、e()が最も高確率でfalseを返す場合、e()を一番左に持って行った方が効率よくなりますよね? あと↑が正しいとして、コードの見栄や保守を考えて順番を変えたくないって場合、どうしますか?
あ、でも関数だから、ショートサーキットな評価は行われないのか… 書いた後に気づいた…
>>868 「その話題」がどの話題かわからないけど、「顔真っ赤」とか刺激してる時点で
たぶん君も「終わらせない気満々」なんだよね。
終わらせようとしているのに同時に刺激してるなら、馬鹿丸出しだし。
>>872 関数が実行されるかされないかによって、プログラムの挙動が変わることがあるから、って思った。
よく考えてみれば、 if (ptr && ptr->func()) とか書きますね・・・
> if (ptr && ptr->func()) これptrがNULLでも安全なの?
871 これでも舐めておちつけ(´・ω・`)つ〔きゃらめる〕
>>875 ptrがNULLなら&&を通らないから大丈夫じゃない?
>>875 ptrがNULLの場合でも問題ない。
でも、ptrがNULLじゃなくても変なとこ指してる可能性は忘れるな。
それだけ見て本当の意味で安全かどうかはなんともいえない。
&&の評価順は左からと決まっている。
>>869 前半部分が正しい。
効率が良くなるが順番を変えたくない場合は個人的にケースバイケース。
効率が求められる部分ならば変更かける。(実測して効果があるかも試して)
とはいえ、関数内に副作用があったり、今後そうなる可能性だってあるから
基本的に短絡評価をあてにした効率は求めないようにしている。
>>875 NULLなら短絡評価でptr->func()は評価されないため問題なし。
881 :
デフォルトの名無しさん :2008/03/13(木) 00:49:53
make && make installみたいなものだよな。
>>869 割と適当に答えるけど、通常見かける && や || は短絡評価をあてにして
cond && (cond が非ゼロの時のみ可能な処理)
や
(非ぜロの確率が低い式) && (非ゼロの確率が高い式)
あるいは
(軽い処理) && (重い処理)
または
(先に必要な副作用のある式) && (その後にのみ評価されるべき式)
等、
すでに正しい順序で記述されているので、並べ替えは不可ということが多いように思う。
もしそうでない場合はコードの質を疑っちゃうから、もしちゃんと動いているならなるべく
触らない⇒やはり並べ替えないだろうなあ。
#include <studio.h> int main(void) { puts("ローゼン「ローザmstcを入れて」"); puts("「次に、目玉を入れて」"); puts("真紅「ぎゃあああああああ」"); puts("ローゼン「あ、順番間違えた」"); return 0; } コンパイル通りません><
質問です。現在猫でもわかるC言語プログラミングというので勉強しているのですが、 関数の再帰呼び出しというところで #include<stdio.h> int main() { static int i = 1; if (i <= 10) { printf("i = %d\n", i); i++; main(); } return 0; } というのがあり、これを実行すると i = 1 i = 2 ・・・ i = 10 になるとなっていて、試してみたところ確かにそうなるのですが、 main内でmainをもう一度呼び出した際に static int i = 1; の部分でなぜ再度 i に1が代入されないのでしょうか? 初心者過ぎてバカかと思われるかと思いますが ご教授願えるとありがたいです。
static i = 1; //宣言かつ初期化 static i; //宣言のみ i=1; // 代入 初期化と代入は違うのです。 下のように書き換えてみるとどうなります?
ごめん、書き込んですぐだけど、そんなプログラムまわすべきじゃないね。 延々回り続けちゃう。 static int i=1; static int j; j=1; if(i<10){ printf("%d %d",i,j); i++; j++ main(); } return 0; } まわすならこっち。
891 :
886 :2008/03/13(木) 05:59:43
なるほど、初期化というのが代入とごっちゃになって、 ちゃんと理解できてなかったことがよく分かりました。 887さん、889さん、ありがとうございました。
vector型で push_backの反対で、先頭に要素を追加するには どのようにすればいいのでしょうか
できません。 listとか使ってください。
そうですか 残念です。すごく これが出来れば完成なのに
単純な質問があります。 Mainループ { @の計算 whilie(永久にループ) { Aの計算 } } このようなプログラムでは、@の計算をし続け、かつAの計算をし続けてもらえると思ったのですが @を一度計算したあとはAの実行をループします。 こういった処理をしたい場合はマルチスレッド処理?というのをしなければならないのでしょうか?
ジャパニーズでおk
>>892 vectorの先頭への挿入は効率が悪いからpush_frontは提供されていない。
どうしても必要ならinsert
無限ループ作ったらずっとそこで回り続けるに決まってるじゃないか。
>>898 ありがとうございます。やっぱりそうゆうものですよね。
待てよお前らwww vectorでpush_frontを使いたいって言われて、なんでlist薦めたり、insert薦めたりなんだよwww deque教えてやれよちゃんとww
>>900 >これが出来れば完成なのに
この言葉に心奪われたんだ。
>>900 dequeにもvectorに劣る欠点はあるしなあ。なんともいえん。
初心者なんざ全部vectorで充分
905 :
デフォルトの名無しさん :2008/03/13(木) 20:39:41
窓の杜も忘れないであげて。
そういえば、去年だかの窓の社で紹介されていたいもうとデスクトップ、 どうやら動くものが出来つつあるらしいな。
C++ の入門書を探しています。C言語の知識はありません。 ネットで検索してみると 柴田望洋『新装版 プログラミング講義C++』(ソフトバンククリエイティブ) 塚越一雄『はじめてのC++』(技術評論社) 日経ソフトウエア編『ゼロから学ぶC/C++』(日経BP社) あたりがC言語の知識が無い初心者にとっての C++ の入門書らしいのですが, この3冊の中で特にお薦めなものとその理由を教えていただけませんか?
すべての書籍を持ってる人なんているのかな?個人的にはどれでもいいと思う。というより、別にネットでもいいのでは? 書籍がいいというのであれば、大きめの本屋にいって立ち読みで少し目を通してわかりやすそうなのを選ぶ。
本気でやるなら三冊とも買えばいいと思う 出費したくないなら入門サイトでも探して勉強するのがいい
910 :
907 :2008/03/14(金) 01:53:06
確かに,3冊とも持っている方はほぼいないでしょうね。 では,この3刷のどれかを読んで感じた長所・短所を教えていただけませんか?
独習と林晴比古ってどうなんだろう。
913 :
デフォルトの名無しさん :2008/03/14(金) 03:14:18
>>912 独習は基礎知識と問題集
林はC言語で知識止まってる
914 :
デフォルトの名無しさん :2008/03/14(金) 08:03:07
林と柴田の本はケツを拭く紙にもならない
C++はロベール見ておけばよくね? ロベールでぐぐれば一番上にくるよ
テンプレート周りまでカッチリやりたかったらC++Primer 4/Eにしとけ。 値段は張るがまあいい本だ。
917 :
デフォルトの名無しさん :2008/03/14(金) 11:43:37
循環小数のことについて知りたいのですが。 vc6.0からC#に移って久しぶりにこの問題に直面 しました。 double d; d=1.2-1.1; が0.0999999になりますが循環小数でない数の 0.0999999とどうやって見分けをつけたらいいのでしょうか。 0.1だけだったら分かるかも知れませんが他にも循環小数が いっぱいあるし自動的に調べられるようにしたいです。 丸めればいいとか1000000倍して必要なときだけ/10000000 すればいいとかいろいろ意見はあるでしょうが単に見分ける方法 とか聞きたいです。
918 :
デフォルトの名無しさん :2008/03/14(金) 11:50:05
プログラムに循環小数は無いだろう 無限の値を保存できない
>>917 double d1 = 1.2 - 1.1; //d1 == 0.099999999999999867
double d2 = 0.099999999999999867;
で、
d1 != d2ということが知りたいの?
その手の誤差は浮動小数点の宿命。 完全に一致したり不一致したりを確認することはできないから、 その計算で出る誤差の最大を取って±誤差に収まってるものを一致するとみなしたりする。 そういう誤差が許されない処理をしたいなら整数型でなんとかするしかない。
921 :
デフォルトの名無しさん :2008/03/14(金) 12:36:02
>>917 一応C++で浮動小数点の比較をやりたいときは、
double a,b;//こいつらには適当な数値がはいってるとして
if (abs(a-b)<=std::numeric_limits<double>::min()) {
// a == b
}
else {
// a != b
}
おれはこんな書き方を習ったけど、これでもすべてのケースを正しく判定できるわけではないからなあ。
あるクラスのメンバ変数に関数へのポインタを与え、 そのクラスのメンバ関数にアクセスしたいのですが、 代入の仕方が分かりません グローバル関数へのポインタなら問題なく出来るのですが
923 :
デフォルトの名無しさん :2008/03/14(金) 12:40:05
int ary[100] = {0}; int100個の配列を0で初期化したいとき、このコードは規格に沿ってますか? 手元のg++だと動くんですが、、、
そもそも 1.2 とか 1.1 とか 0.1 って定数が正しく 1.2 や 1.1 や 0.1 を表してるわけじゃないから、 正しく判定ったって、何がどう正しいのやら
>>923 沿ってない
ary[1]〜ary[99]は初期化されない
927 :
922 :2008/03/14(金) 12:57:06
>>925 ちょっと説明不足でした
インスタンスごとにポインタに代入するメンバ関数を変えたいんですよね
main関数内で宣言・代入する方法はいくらでも見つかるんですが、
コンストラクタのようなメンバ関数内で宣言・代入する方法が分からなくて
こうか? class Foo { public: void (Foo::*func)(); Foo(int){ func = &Foo::bar; } Foo(bool){ func = &Foo::hoge; } void foo(){ (this->*func)(); } void bar(){ cout << "bar"; } void hoge(){ cout << "hoge"; } }; int main() { Foo a(1); Foo b(true); a.foo(); b.foo(); }
>>923 C++なら規格に沿ってる
Cだと沿ってなかったような気がするが…
>>928 それです!
>void (Foo::*func)();
ここが分かっていませんでした
ありがとうございました
931 :
デフォルトの名無しさん :2008/03/14(金) 13:49:37
>919 そうです。 >921 確かに整数値に直すしかなさそうですね。 丸める方法も0.00001の誤差を判定するときも 0.09999の次の9を丸めて0.1にしたらえらい違い になりそうな気がするし。 確実に循環してると分かっているなら丸めてもいいと思うけど そうでない場合は困るね。 >921 それでも確実じゃないと言われると絶望的? VC6.0はどうやって判断していたんだろう。
>>930 >main関数内で宣言・代入する方法はいくらでも見つかるんですが
これ嘘くせえな
おまえちゃんと読んでないだろ
933 :
デフォルトの名無しさん :2008/03/14(金) 14:08:50
しつもんです。 int hoge [][3] = { {0,0,0}, {1,1,1}, {0,1,0}, }; のような配列で hoge[1]; とやると hoge[1][0]のアドレスを返して来るでよろしいでしょうか?
>>931 別に循環はしてないよ
これ実行してみ
int main()
{
printf("%.70f\n", 1.2);
printf("%.70f\n", 1.1);
printf("%.70f\n", 1.2 - 1.1);
}
936 :
デフォルトの名無しさん :2008/03/14(金) 14:24:19
>>931 どうやって判別しているのかは、仮数部と指数部が完全一致だろう
937 :
デフォルトの名無しさん :2008/03/14(金) 14:28:56
>>934 うん。
int a[3];でa==&a[0]なのと一緒だからね。
938 :
デフォルトの名無しさん :2008/03/14(金) 14:29:38
扱う数によってどの位の誤差ならいっちしていると見なすか各自で判定すればいい 100億と100億1くらいならば同一と見なすとか・・ 0.0001なら1の誤差は大きい GOSA = 0.999と定義して、x = yであることを x*GOSA < y < x/GOSA としたらどうか?
939 :
デフォルトの名無しさん :2008/03/14(金) 14:33:04
計算量を減らすなら 0.999 < x/y < 1.001 の判定にすれば良いか
940 :
デフォルトの名無しさん :2008/03/14(金) 14:49:12
>935 すいません。VC6.0からC#間がないので、 stdio.hをインクルードする方法(できるの?)が分かりません。 代わりに次のようにしてみたら・・・、 static void Main(string[] args) { Console.WriteLine(1.2 - 1.1); } 0.0999999999999999 となりました。
941 :
デフォルトの名無しさん :2008/03/14(金) 14:51:41
>939 なるほど。参考にしてみます。
942 :
デフォルトの名無しさん :2008/03/14(金) 15:01:04
初めに|x - y| < 1 などを調べておくと高速化できるな
943 :
デフォルトの名無しさん :2008/03/14(金) 15:03:12
仮数部、指数部を直接調べていけばより高速化出来るな 指数部が2以上ずれていれば駄目だろう
>>940 C#ならdecimal型を使えば解決
static void Main(string[] args)
{
decimal d = 1.2m - 1.1m;
Console.WriteLine(d);
}
初心者スレで
>>926 みたいな嘘付くのは良くないよね・・・
946 :
デフォルトの名無しさん :2008/03/14(金) 16:00:02
#include <iostream> #include <cstdlib> using namespace std; int main() { cout << rand() << endl; cout << rand() << endl; } このようにプログラムをコンパイルし実行してみると何度やっても 0 1481765933 となります。乱数当てプログラムみたなのも全部0が生成されてしまいます。 コンパイラはcygwinのg++です。なぜなんでしょうか???
>>946 しょせん擬似乱数だから
srandで異なるシード値を与えれば変わる
class X { public: const int tbl[2]; }; 非staticでconstの配列をメンバーに持たせることは可能ですか?
>>948 こう?
class X {
public:
const int tbl[2];
};
int main() {
X x = {{96,43}};
cout<<x.tbl[0]<<x.tbl[1]<<endl;
}
950 :
デフォルトの名無しさん :2008/03/14(金) 16:54:23
>943 ここまでしないとだめ? 確かにそれだと指数部を見ただけで二つの値が違うかどうか 分かりそうだけど。
951 :
デフォルトの名無しさん :2008/03/14(金) 17:00:01
>944 いいですね。しかし128ビットも使うのは少し嫌ですね。 unsigned short decimal とか使いたい^^
>>946 ちゃんとsrandにガンダムシードを与えないと。
>>949 説明不足でした。
コンストラクタで初期化できるかどうかです。
もう少し込み入ったクラス
class X {
public:
int mi;
virtual void mf();
double md;
private:
const int tbl[2];
};
955 :
バラ :2008/03/14(金) 17:31:15
c言語で ”山田太郎”は0008バイトあります。 とmystrlenを使ってと表示させたいのですが やり方教えてください。 お願いします。
#define mystrlen strlen
958 :
バラ :2008/03/14(金) 17:48:53
956 mystrlen関数だけをを使いたいのですが。 strlenは使用禁止だそうせす。 詳しく教えてください。
宿題スレ行け
> strlenは使用禁止 仕方がないな。 int mystrlen(const char*p){ return strchr(p,0) - p; }
961 :
デフォルトの名無しさん :2008/03/14(金) 17:55:00
素直にdecimal型を使うことにします。 皆さま、いろいろとありがとうございました。
962 :
バラ :2008/03/14(金) 17:57:35
ほ〜^^。 ありがとうございます。
まず間違いなく先生にツっこまれるな
じゃあこれでどうだ? int mystrlen(const char *str) { char buff[512]; return sprintf(buff, "%.500s", str); }
void mystrlen() { printf("\"山田太郎\"は0008バイトあります。"); } 一応質問文からだとこれでもあながち間違いじゃない
966 :
バラ :2008/03/14(金) 19:20:51
#include <stdio.h> #include <stdlib.h> #define STRING "山田太郎" int mystrlen(char *p) { /*i初期化*/ int i = 0; /*\0ならば抜ける*/ while(*p != '\0') { /*pを増やす*/ p++; /*iを増やす*/ i++; } /*iを返す*/ return i; } int main() { /*バイトを表示*/ printf("%s は %04d バイトです.\n", STRING, mystrlen(STRING)); /*0を返す*/ return 0; } できました。ありがとうございます
圧倒的なひらめき っ BCD
「先生に車輪の再発明は不毛です。」と告げるのじゃ。
車輪の再発名は勉強にはいいのじゃ。
970 :
パラ :2008/03/14(金) 19:38:27
何をどうやっても山田太郎が12バイトになってしまいます… どうやったら8バイトにすることでができるんでしょうか…
関数ってなんですか?
UTF-8 なら 12 バイトだから正常だと思うぜ。
この歳では中学校に通う暇がないんです>< c++における関数の定義が知りたいんです><
その歳なら本買え。
本を買いに行ってる時間が無いんです>< 今教えていただけませんか?><
ならググれ。 C++ の入門サイトがあるだろう。
googleで検索したほうが時間の節約になる
問題解決能力がないとこの先生きのこれないしな。
なんで皆さんそんなに冷たいんですか?>< 分かる人から分かりやすく聞いた方が理解しやすいと思って書き込んだのに!>< 何のための掲示板ですか?!><
お前のためを思ってるからこう言ってるんだ。 こんな質問するなんて、お前のこの先が凄く心配だからな。
分かりました。さてはあなたたちも説明できないのですね>< 説明してくれる人が現れるのを待つことにします。 このスレッドが1000行くまで待ちます><
f(6)=2 fが関数。中の構造は何でもいい。
ラーメンうめえwwwwwww
誤爆しました><
これはひどい
985さん つまりc++の関数とはサブルーチン機能のことなんですね!>< ありがとうございました>< ラーメンおいしいです
スレ違いかもしれんが自転車こいで電力ためるのってどういう装置がいるんだ?
蓄電池だろ
重りを上に上げて、位置エネルギーから電気を取り出す機械ってのもあったな スレチだが
揚水発電もその一種だな
今更だけど本屋行く時間はないのに誰かが答えを書くのを待つ時間はあるんだな。
>>994 乙
>>989 発電機もいる
コイル+磁石 で電磁誘導がどうたら
発生する電流は交流だから整流してこうたら
蓄電池に充電する際には一定以上の電圧(蓄電池による)が必要になるからうんたら
で、スレチというより板違い
どう考えてもスレチなのに答えてくれるお前らに感動した
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。