【初心者歓迎】C/C++室 Ver.50【環境依存OK】 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を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。