【初心者歓迎】C/C++室 Ver.56【環境依存OK】
◆ソースのインデントについて 半角やTABでのインデントはスレに貼ると無くなります。 そのため、アップローダーに上げるのが最も良いですが、 直接貼るのであれば、全角空白か に置換しておくことをお勧めします。
1乙
テスト
前スレ999はツンデレ
C++の仮想関数についてです これって派生先でオーバーライドするなら とりあえず派生元にvirtual書いてしまってておk? 書いてて弊害起きるのかな?
むしろ派生元にvirtual書かないといけません。
いつも当たり前のように書いてたけど、むしろ書かないとどうなるんだ?
オーバーライドと仮想関数は抱き合わせ商品なんですか。thx でも、仮想関数とオーバーライドの説明を 別個で説明してるケースが多いのなんでだろ
>>8 struct A{
void f(){ std::cout << "A::f" << std::endl; }
};
struct B : A {
char* p;
B(){
p=new char[100];
std::cout << "new p" << std::endl;
}
~B(){
delete[] p;
std::cout << "delete p" << std::endl;
}
void f(){ std::cout << "B::f" << std::endl; }
};
void test(){
A* a = new B();
a->f();
delete a;
}
--出力--
new p
A::f
※ pはdelete[]されない
某C#ではオーバーライドと隠蔽をこれでもかってくらい区別してる それは置いといて継承先にvertualをつけるかつけないか議論になってたことがあるな
12 :
10 :2008/07/06(日) 11:20:42
ちょっと訂正。Bにvirtual付いてなかった。 struct B : A { virtual ~B(){... virtual void f(){... ... }; 出力結果は同じ。
あー、なるほど インスタンスはBでも、Aとして振舞うのか デストラクタが呼ばれないのは、よくわからんが
>>11 C#やJavaなどでオーバーライドだと明示するようになってきてるから、
明示した方が良い、という流れなんだろうね。言語設計者達の中では。
>>13 (A*)new Bとして使う場合は、
Aのデストラクタと仮想化したい関数にvirtualを付けておく必要がある。
デストラクタもオーバーライドしないとまずいってこと。
本来ディフォルトで virtual にした方が安全なんだけど C との互換性が崩れるのでできなかった。 個人的には、struct と class をもっと別のものとして 定義すべきだったと思う。
virtual宣言すると、クラスサイズが増えるぞ
遅くなるしな。『安全、便利』は効率を犠牲にしない限りなるべく やりましょうってのがC++のスタンス。 virtual書かなかったときのコンパイル後のイメージが浮かばん奴は 仕事でC++使うべきじゃない。っていうか意味分からないのにvirtual 書くなよ… あ、遅くなるっていうのに対して、今時のCPUなら問題ないとかいう レスはいらないから。
>>『安全、便利』は効率を犠牲にしない限りなるべく やりましょうってのがC++のスタンス。 言いたいことは分かるが、「『安全、便利』は効率を犠牲にする場合はやらない」と書くべきでは。
サイズが増えるとか遅くなるって言ってる奴は、ちょっと 頭おかしくないか? 同様のことしようとしたら C でも、似たようなもんだろ。
いや・・・何振り構わずvirtual付けるバカの話だろ 必要なら付けろよ
>>19 >犠牲にする場合はやらない
そこまで強くないっしょ。軽微な効率ダウンと引き換えに
RTTIや例外は導入されたからね(そんなニュアンスのことが
ARMかD&Eにあった気がする)
>>20 >頭おかしくないか?
そこまで言われる筋合い無い。サイズ増えて遅くなる理由が
わかってるなら問題ないことだし。
構造体がよくわからない、構造体勉強するのにいい本ない?
>>24 箱をしまう箱っていうのはわかるんだけど、その中で関数書いたり
引数なしでおkのくせに、構造体で宣言されてる中の変数は使えるとかがいみぷーなんです。
int型という名前の小皿があるとしたら、それを乗せる御盆が構造体とか ん〜・・・どうやれば理解できるのか
Cでも構造体に関数って作れるんだっけか?
Cの構造体はただの器
ああ、すいませんC++の話です。 Cより新しいならC++のがよくね?ってC++の勉強してたら構造体単体なら分かりますが 構造体内で関数とかがいみぷーで。
C++ならクラスを勉強したほうが良さそうよ
>>28 なのか
C++から入ったから細かいことはよく知らんのだ 情報thx
>>29 基本的に構造体とクラスってあんまり変わらないよ
実装的な違いでは、デフォルトのアクセス指定子がpublicなのかprivateなのかぐらいしか無いらしい
意味的な違いでは、構造体はデータ中心でクラスは関数中心として使うといい
構造体やクラス内・・・いわゆるメンバ関数は、自分自身のメンバ変数を操作するためにあると思っとけばいい たとえば、エレベータというクラスがあるとして、メンバ変数に階数があるとしたら、 アップというメンバ関数でメンバ変数が変動するとか
俺は、メンバ変数がパブリックにしたい場合は構造体 完全に隠ぺいしたい場合はクラスにするって感じかな Getter/Setterを定義するのが無駄なくらい小規模なら、まず構造体
>>25 struct A {
int n;
A() { n = 0; }
void func(){ n += 10; }
};
void test(){
A a;
a.func();
}
これはつまり
struct A {
int n;
}
void A_ctor(A* this) { this->n = 0; };
void A_func(A* this) { this->n += 10; };
void test(){
A a;
A_ctor(&a);
A_func(&a);
}
ということ。
>>34 そうする過程で関数中心の時は必要だったものがデータ中心になると
関数中心とは別な考え方しなくてはいけないわけで、データ中心の考え方というのがわからない
>>35 何言ってるか分からない・・・w
仮想関数など使わない限り、別な考え方とか要らないと思うけど。
構造化プログラミングとオブジェクト指向プログラミングの話?
this-> を表記するかしないかって完全に好みですか? VC++だとコードの候補が出てきて楽なんですが 込み入ったところだとごちゃっとした感じになってしまって もちろんなるべく見やすく書くように気を付けているんですが どうしたモノかと迷ってて。
>>35 別に全ての関数を構造体に入れないといけないってわけじゃないよ
>>37 メンバ変数とかには基本m_ とか付けてる
けど何が一番良いのかは知らない
40 :
デフォルトの名無しさん :2008/07/06(日) 18:22:50
OSがWindowsXPでコンパイラがBCCです。 コマンドプロンプト上に特定フォルダ配下の全テキストファイルを表示 ↓ ファイルを選択 ↓ ファイルを処理 という流れを作りたいのですが、 ファイル表示、ファイル選択は可能でしょうか? 可能なら、どうすれば実装できますか?
>>40 です
あ、言語はC++です。失礼しました。
初心者だと、メンバ関数を「クラス(or構造体)の中に入った関数」と考えてしまって、 「関数が入ってる、ってどういうことだろう?」みたいな疑問に振り回されちゃうことが あるかもしれないね。
m_はいわゆるシステムハンガリアンだな 一般的に批判的な声が多いコードでもあるが、コンパイラ依存度や可読性を考えたら、ありだと思ってる
>>40 BCCはファイル表示もファイル選択も不可能だった希ガス。
VC++6.0ならできますよ。
>>40 方法1 コンソール系のAPIをいじって対話型に選べるようにする。
方法2 ファイルに番号をつけて一覧する。番号を入力させて選択に代える。これならスクロール型のI/Fで可能。
方法1はDOS時代にエスケープシーケンス使ってやってたなぁ〜
this 使うとメンバ変数だけじゃなくてメンバ関数も候補に挙がるから m_ だとメンバ変数だけに絞れて良いかなって個人的に思っては居るんだが そういう話って良い悪いじゃなくて、一貫したコーディングスタイルであるか? が問題な事が多い気がするし正解なんてないよね
text vram直書きだったなw
なるほど、色々参考になります。 m_ ですがシステムハンガリアンが型のプリフィクスを多く使うのに対して クラス内、外を区別できるので個人的にはアプリケーションハンガリアン寄りかなと 思っているのですが、これはちょっと自分に誤解があるのでしょうか。
>>37 この辺は好みが別れるから一貫性が保ててればいいと思うよ。
個人的には
全部に this-> は冗長っぽい
m_val や val_ は悪くはないが、publicなフィールドにはちょっと
_val やってたらちょっとこい(笑
>>44-45 ありがとうございました。方法1を調べてみます。
ヴィジュアル系の環境、さっぱりわからんので、方法1が向いてそうです。
う、カーソル位置を保存しておく変数に Cursor_pos て名前は駄目でしょうか
ちなみにグローバル関数には頭に::付ける派 Win32の場合だけど
さすがに変数の頭文字が大文字なのは引っかかるなw プレフィックスがCursorってことか? カーソル位置と言っても、絶対座標と相対座標と色々あるし、しっかり設計してから決めた方がいいぞ
アプリケーションウィンドウに対する位置なので 相対座標でしょうか(意識したことがないので) 名前の付け方でいつも四苦八苦なのも思い出しました…
C++でのエラー処理はintの返り血を 返すような設計にするべきなんでしょうか? それとも全部例外処理で実装するべきなんでしょうか
googleは例外を使わない方針だそうだ。 コンストラクタで実行時エラーが起きたらどうしてるんだろうか。
実行時エラーの時どうやって回避してるんだろう
・new_handlerかなんか ・newをオーバーロードしてるか ・コンストラクタで実行時エラー起きるようなことしない ・そもそもメモリ不足とかは無いものとして組む
コンストラクタが「bool& result」って出力パラメータがあるとか、 すべてのクラスの基底になってるクラスに、 「newされたかどうか」って示すフィールドがあるとか。 ....めっさ素人ぃな発想で住まん。
std::nothrowでいいだろ。阿呆かw
結構以外だった。C++ではなくベターCとして使ってる印象だな。
C++について質問です HANDLE HogeFile = ::CreateFile(); このダブルコロンの意味を教えてください。
:: はスコープ演算子 この場合どの名前空間にも属してない = グローバル空間に属してると考えると良いと思う
>>65 ありがとうございます!残りは自分で調べます!
>>37 全部に this-> つけないと一貫性がない気がするんですが。。。
ところでthis->で区別できるからといって
メンバ変数とローカル変数を同じネーミング規則にするのは危険だと思う。
他人が保守したときにバグになりそうなので。
(this->をつけるのを強制できないしね)
C++で(他の言語もそうなのかも知れないんですが) 先ほど全角スペースによるコンパイルエラーというものを知りました。 調べてる時に思ったんですが 全角 × 半角 ○ インデント・・・? インデントは使っても安全なのでしょうか? それとも安全とわかりきっている半角スペースを使うべきなのでしょうか?
インデントは字下げのことであって それ自体が全角スペースだとか半角スペースだとかは無い 別にTabでインデントしても良い
>>68 空白文字 : 半角スペース、TAB、改行
非空白文字 : 全角スペース 他
半角スペースかTABを使って下さい。
>>69 >>70 なるほど、文字としての種類というか、扱いが違うんですね。
ありがとうございました。
>>71 >>2 にある、全角スペースの話は、
こういう掲示板で他人に「みせる」ときに使ってね。という話
(果てしなく意味のないコードだけど気にしない(゚ε゚))
//半角スペース
if(true){
int hoge; //インデントしてます
}
//全角スペース
if(true){
int hoge; //インデントしてます
}
とまぁ、前者はスペース入れても掲示板の仕様で消されてしまい見にくくなる
全角半角の違いはアスキーコード(ASCII CODE)を調べるべし
その手の話はC言語の定番の練習問題でもある
>>72 Cの定番というより、PCの基本じゃないか。
>>72 詳しい解説ありがとうございます。
>>73 そうですね、ちょっと調べればわかる事でした、失礼しました
> とまぁ、前者はスペース入れても掲示板の仕様で消されてしまい見にくくなる これはまあPCの基本になるのかもしれないね。 HTMLにおける連続したスペースの扱いに関する知識。 > 全角半角の違いはアスキーコード(ASCII CODE)を調べるべし けど、定番の練習問題がかかっているのはこっちでしょ
自作クラスでDCを取るにはどうすればいいんですか? おねがいします。 // MFCダイアログ void CRS232C_TESTDlg::OnBnClickedstart(){ CClientDC* pDC( this ); AfxBeginThread( drawData::DrawThreadFunction, (LPVOID*)&pDC, THREAD_PRIORITY_HIGHEST ); } // 自作クラス class drawData : public CObject{ static UINT __cdecl DrawThreadFunction( LPVOID pParam ){ CClientDC* pDC( pParam ); //成功させたい場所 }}
ウィンドウはあるの? あるならGetDCすればいいし、無ければCreateDCするしかないかな。 CreateDCするにはどのデバイスのDCかの指定は要るけどね。
ってもしかして pParam がCWndのポインタならキャストすればいい。
79 :
デフォルトの名無しさん :2008/07/07(月) 18:50:05
ダイアログウィンドウあります。 基本クラスCObjectで作ったのに既定のコンストラクタがないと言われてしまいます CWndはキャストできないと言われてしまいます // MFCダイアログ void CRS232C_TESTDlg::OnBnClickedstart(){ AfxBeginThread( drawData::DrawThreadFunction, this, THREAD_PRIORITY_HIGHEST ); } // 自作クラス class drawData : public CObject{ static UINT __cdecl DrawThreadFunction( LPVOID* pParam ){ //CClientDC* pDC( (CWnd*)pParam ); CClientDC* pDC; pDC = pParam->GetDC(); }}
ありがとうございます!LPVOIDの*を取ったらコンパイルできました。 が、なにも起動しませんw
template <class T> void WriteData(T data); のような関数内で、dataのサイズを知りたいのですが、どうしたら良いのでしょうか。 sizeof(data)を行うと、明らかに正しくない値が返ってくるみたいなのですが、、、
あ、すみません。動いていました。 なんだか手違いで動いてないように見えただけみたいですorz
CWndとかCDCとかHDCとかHWNDとかって、 スレッドアフィニティがあった気がするけど
!0 の値は必ず1であると保証されているのでしょうか。 中には0以外の値と書かれてますが。そういう場合もあるのでしょうか。
>中には0以外の値と書かれてますが。 これは、中には「0以外の値」と説明しているところもあるという意味です。
86 :
デフォルトの名無しさん :2008/07/07(月) 22:04:55
論理否定演算子!の結果はそのオペランドの値が0と比較して等しくない場合0とし、等しい場合1とする。 結果の型はintとする。式!Eは(0==E)と等価とする。 保障されてる
ポインタ変数をconst宣言することは出来ますか?
できます。
ありがとうございます
やり方とか聞かなくていいのかw
Detected memory leaks! ってどうやって解除すればいいんですか? PC再起動するまで直らないんですけど
Detected memory leaks!
deleteすればいいと思うよw
やっとわかった カスタムコントロールは配置するだけだとメモリリークする
97 :
デフォルトの名無しさん :2008/07/08(火) 12:04:40
関数内でエラーが起きたときって -1を返すべき? それともNULL? あとassertとperrorってどう違うの?
gnome-terminalについて。 まずTESTって実行ファイルを作成したんだ ただハローワールドが表示されるだけのプログラムなんだけど gnome-terminalでもう一個ウインドウ立ち上げて引数に 実行ファイル名指定してるんだが新しいウインドウに ハローワールドが表示されない。 どんな感じで実装したらいいのかな? もしスレチならごめん
>>97 > -1を返すべき?
> それともNULL?
ケースバイケース
> あとassertとperrorってどう違うの?
マニュアル読めばわかる。
読んで分からないのなら、どう分からないのか書け。
101 :
デフォルトの名無しさん :2008/07/08(火) 12:30:14
>>99 >ケースバイケース
とか分かってんだよ
慣例とか具体例とか使って教えてちょ
perroとassertは調べるわ
どっちもあるから。 自分で決められないならママに聞け。
>>101 それは今回の君の状況を具体的に書くのが先だよ。
104 :
デフォルトの名無しさん :2008/07/08(火) 12:42:22
vs2005 のc++でWin32プロジェクトで作ったexeが 他所の環境だと動かないらしく、調べてみると VC++2005 が入っていない環境では VC++2005のランタイムが必要だとかいう記述などに行き着きました。 これはどんな状態にもかかわらず、そういうものなんでしょうか? それとも、こちらのコンパイル時の設定などによってどうなかなったりするんでしょうか? あるいは単純にVS2008買ってコンパイルすればOKとか・・・ よろしくお願いします。
動かない、ではなく具体的な現象を書け。 エラーメッセージが出るのならコピペしろ。 考えられるのはデバッグビルド版を配布してるとか。
>>104 ランタイムライブラリを「マルチスレッド DLL」ではなく「マルチスレッド」にする
108 :
デフォルトの名無しさん :2008/07/08(火) 13:16:57
>>105 基本的なことを忘れてました。すいません。
エラー:
このアプリケーションのサイド バイ サイド構成が正しくないため、アプリケーションを開始できませんでした。
詳細については、アプリケーションのイベント ログを参照してください。
そのログ:
Microsoft.VC80.DebugCRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="8.0.50608.0" が見つかりませんでした。
詳細な診断を行うには sxstrace.exe を実行してください。
とかいうものです。
その後ですが、
>>106 さんに教えてもらったように
「マルチスレッド デバッグ (/MTd)」にしたら動いたようです。
(ただの「マルチスレッド」はリリースビルドしないとビルドできないのは、それで正しいんですよね?)
でもこれの意味ってなんなんでしょうか?
できるだけ噛み砕いて教えてもらえると助かります。
109 :
108 :2008/07/08(火) 13:32:25
あら、すいません。
>>107 に書いてありました。
なんとなく分かったような分からんような。
ちょっとお勉強してきます。ありがとうございました。
クラスが角度を表すメンバ変数もっているのですが、 値が常に0から360度になるようにしたいのです 500度を代入したら140度が格納されるように しかし、いちいちsetterを経由したくありません C#だとプロパティでかのうですが、C++で同じようなことはできないでしょうか
112 :
デフォルトの名無しさん :2008/07/08(火) 17:43:11
>>111 値を格納するときに、チェックしろよ。 x を入力したとき
x - 360 * {x/360}
{y}はyより小さい方のほうの整数に変換する
整数なら、x %= 360 じゃだめか。
VC++なら独自拡張で__declspec( property(〜))がある。 それか角度クラス作って演算子オーバーロードでなんとかするとか。
型変換がうまくいかないので教えていただきたいのですが、 const double T = 12; const int A = (int)T; int B[A]; とすると、エラー:定数式が必要 と言われてしまいます。 Tはdoubleの必要があるので、これを変換する方法を教えてください。
const int A = 12;
const double T = 12; const int A = (int)T; int B[12];
118 :
デフォルトの名無しさん :2008/07/08(火) 18:17:05
#define N (12) const double T = N ; int B[N] ;
119 :
115 :2008/07/08(火) 18:20:03
配列がいろいろなところにあり、値を変えるときにすべての場所を変更するのが大変なので
変数をひとつにしたいのですが・・・
>>116 さんのも、値の変更忘れが怖いので出来たら一元化したいです。
const double 型を const int 型に変換することは出来ないんですか?
何でエラーが出てるか分かってるか?
121 :
115 :2008/07/08(火) 18:29:08
わかりません
配列添え字には整数を使いましょう。
const int には整数の定数式を入れましょう。
ほぼ総てのプログラマーは部下から
>>115 のプログラムを見せられたら。転職を進めるでしょう。
C99でおk
>>105 知らないやつがしゃしゃり出てんじゃねーよ
後から出てきて文句だけは一人前だな、おまえ
127 :
デフォルトの名無しさん :2008/07/08(火) 19:40:14
解決はしたんですが 最初の文でうまく実行できない理由が分からないので、再度質問させてください。 A はなぜ整数の定数式ではないのですか? 整数でないのか、定数式でないのか・・・。いろいろ試しましたが分かりませんでした。
コンパイル時定数ではありません。以上
一言でconstってなんですか?
あ
青春?
今からCを勉強したいでちゅので図書館行ったんですけど、最新バージョンのC99準拠の入門書を探したが、 まったく見つからないわけだが。Cはどうしたの?死ぬの?
134 :
デフォルトの名無しさん :2008/07/08(火) 19:54:09
c++てやつ
>>128 いつ定数になるんですか?
>>129 変数を定数にする修飾子だと認識してます。
const double T=12;
const int A = (int)T;
// int B[A];
で実行したらエラーはでない = Aは定数の整数と定義(?)されいる
のに、なぜAを配列の添え字に使えないのかが分かりません・・・。
>>131 プログラムを見直したらTがdoubleである必要が無かったのでintにして解決しました。
136 :
84 :2008/07/08(火) 20:14:57
137 :
デフォルトの名無しさん :2008/07/08(火) 20:37:06
>>102 ,103
具体例を書けば教えてくれるなら
何かしらのルールがあるわけでしょ?
その指針を教えてください,と。
あと具体例はないんです
常々関数作ってるときに思ってる疑問なんです
このスレ笑えるわ
>>137 CやC++で無効ポインタはNULLとか0だけ。
これ以外の値は「有効なポインタ」と区別がつかない。
だからポインタを返す関数は、失敗時に-1を返すことはあり得ない。
エラーコードを返す種類の関数で、
失敗したときに-1を返すべきか0(NULL)を返すべきかだと、-1のほうがいいことが多い。
なぜなら関数の成功を0で表す場合が多いから(=成功の状態は一つしか無いことが多い)
エラーはエラーの種類によって0以外のいろんな値を使うことが多い。
でも、関数によっては成功時に非0を返した方がいいかもしれない。
条件式では「真」として評価されるから。
この辺はほんとうにケースバイケース。
140 :
デフォルトの名無しさん :2008/07/08(火) 20:59:18
typedef struct{ int a; int b; }DATA; という構造体を定義しmain関数で DATA hogeと宣言します これを関数に渡して処理したいんですがどうかけばいいですか int func(DATA hoge){ } だとエラーになります・・・
>>137 Cなら成功時に0を返す
C++ならboolを返せば悩まなくてすむぞ
>>140 それでエラーが出ませんが
どのような書き方でどのようなエラーが出てるんでしょうか?
144 :
デフォルトの名無しさん :2008/07/08(火) 21:05:18
>>142 'func : 関数に 1 個の引数を指定できません。
とでます。
構造体の宣言の時にDATA *hoge;
ってなってました。
これは他人が書いた部分でSound hoge;ってできません
145 :
デフォルトの名無しさん :2008/07/08(火) 21:06:42
hogehoge##className とかってなんなの? define文とかで出てくるんだけど。 先にhogehogeとclassNameのdefineを解釈して その後に単語として連結するって意味? VC++なんだけど
147 :
デフォルトの名無しさん :2008/07/08(火) 21:10:22
>>144 typedef struct{
int a;
int b;
} DATA;
int func(DATA *hoge);
int main()
{
DATA *hoge;
func(hoge);
return 0;
}
int func(DATA *hoge)
{
return 0;
}
これで通るよ
149 :
144 :2008/07/08(火) 21:11:14
これは他人が書いた部分でDATA hoge;ってできません に訂正します
150 :
144 :2008/07/08(火) 21:13:01
できました。 プロトタイプ宣言のところを書き換えるの忘れてたせいでした。。。 すいません
大体分かったけど日本語何とかした方がいい
わかったのか。おめでとう
153 :
144 :2008/07/08(火) 21:25:08
センター試験英語リスニング ∧_∧∩ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ( ´∀`)/<先生!!なぜか僕には理解できない外国語が流れます! _ / / / \ 故障ではないですか? \⊂ノ ̄ ̄ ̄ ̄\ \_______________ ||\ \ ||\|| ̄ ̄ ̄ ̄ ̄|| || || ̄ ̄ ̄ ̄ ̄|| .|| ||
>>145 空白無しでくっつけると覚えておけばいいと思う。文字の置き換えするだけだし。
#define a(x) x ## f
#define b(x) a(x)(#x)
b(print);
printf("print");
単純にソースコード情報文字を連結すると思えばいい 文字列ではなく
bccでnewの例外がキャッチできません。どうなってるの?
再現する最小のコードを張ってごらん。
160 :
デフォルトの名無しさん :2008/07/09(水) 01:42:25
仮想関数について勉強していて思ったのですが、 virtualと付けてもオーバーライドしなければそのまま使えるのであれば 関数にはとりあえずvirtualと付けておけば良くないですか?
よくない
本当に必要な関数だけにしとけ 誤解を招くことあるし、パフォーマンスも落ちる
163 :
デフォルトの名無しさん :2008/07/09(水) 01:59:37
どうしてですか?名前が被らないように少し気をつければいいだけではないでしょうか。 パフォーマンスの低下以外に何か大きなデメリットはあるのですか?
#include <iostream> #include <new.h> class test{ int *array; public: test(int x); ~test(){delete [] array;}; }; test::test(int x = 1){ try{ array = new int[x]; }catch(bad_alloc&){ std::cout << "bad_alloc" << std::endl; abort(); } }; int main(){ test *a; while(1) a = new test; return 0; } // 実行結果 // // Abnormal program termination //
#include <iostream> #include <new.h> int main(){ int *array; while(1){ try{ array = new int[10000]; } catch(bad_alloc&) { std::cout << "bad_alloc!!!" << std::endl; abort(); } } return 0; } // 実行結果 // bad_alloc!!! // // Abnormal program termination // こっちだとうまくいくんだが・・・
一番大きなデメリットを教えよう。 そのプログラムを、ちゃんとしたプログラマーに見せたら。 「君、もう帰っていいよ」 と言われて。 君がダメプログラマーであるレッテルを貼られる。
>>160 > 関数にはとりあえずvirtualと付け
「とりあえず」が非常にまずい
なぜそう思われるのかが分からないから質問してるんじゃないの? ちゃんと教えてあげてよ。 俺C++わからんから答えられないけど、そのレスはかわいそうだわ
メンバメソッドはデフォルトで仮想関数なD言語でも使ってればいいよ。
>>169 知りたければ、ネットでも本でも読めばいい。ここは教育を行う場ではない。
調べて分からなければ、そのわからないところを聞くべきと思われ。
ついでに自演乙。
172 :
デフォルトの名無しさん :2008/07/09(水) 02:24:21
>>170 そのような言語があるということは、
仮想関数がデフォルトであることに致命的なデメリットは無いということですね?
ならば何が「ダメ」で「まずい」んでしょうか?その方が便利だと思うのですが。
173 :
デフォルトの名無しさん :2008/07/09(水) 02:25:28
俺は実際に仕事でやってるわけでもないし、チームでやったこともないから想像だけど 全部virtualにする危険性はなんとなく想像できる つまり公衆の面前で全裸はマズイということだ
>>160 俺はPHPのOOPしかまともにやった事がないと事前に言い訳させといてね
C++ってvirtual付けてないと親クラスのメソッドとして実行されちゃうと思うんだけど、
それだと、継承先の子クラスの方で「あれ?オーバライドしたのに親クラスの動作に
なるぞ?」ってなるんじゃない?
たとえば、親クラスで以下のメソッドがあるとする
・Hoge::testMethod() { cout << "親クラスですよ"; }
で、これを子クラスのほうでオーバライドする
・Foo::testMethod() { cout << "子クラスですよ"; }
これで、子クラスのインスタンス作ってtestMethodを実行したら実行結果が、親クラスですよ
っていう結果になってしまうのだよ!
※ Foo* fooInstance = new Foo();でインスタンスを作った場合
ただし、Fooインスタンスを作る場合に、上の例みたいに参照先を設定するんじゃなくて、
Foo fooInstane
見たいな作り方すれば意図した動作をするみたい(子クラスですよが表示される)
ただ、インスタンスの作り方なんて人が変われば異なってくる可能性があるから、オーバライドするなら
virtual付けといた方がいいと思う。
多分間違ってないと思うけど参考程度に・・・
>>163 大きいデメリットかどうかは状況によるけど、
あまり良くはない。
・デフォルトで非仮想なC++では、virtualが付いていると
オーバーライドして欲しいというセマンティクスが強くなる。
そのため、逆に本当にオーバーライドすべきものが分かり辛くなる。
・通常、継承よりコンポジションの方が良い。
オーバーライドは、元のクラスの実装を知っている必要があることが比較的多く、
より依存性が大きくなる。
・仮想化のためにvptrというのが付加され、
インスタンスのサイズも増える。
・本当に多様が必要な場合はともかく、単に機能を追加する場合は、
バイナリのサイズとのトレードオフはあるものの、
テンプレートでの拡張の方が良いことが多い。
こちらの方がコンパイラの最適化がよりよく働く。
>>167 何が非常にまずいんだ?
>>166 ,
>>168 キメェレスだな
177 :
175 :2008/07/09(水) 02:48:18
あ、これだとただ単にvirtualの説明で、
>>160 の質問に答えられてないな・・・すまんこ
よく考えるとJavaとかPHPの親クラスには原則virtualがついてるような物かもしれんね。
ちなみに
>>163 の名前が被らない様に気をつけて〜という部分なんだけど、この部分に
関しては仕事では宜しくないと思う。気をつけててもやっちゃう事が可能性としてある訳
だから理想としてはそもそも出来ないようにしておくべきだね。
個人とかある程度見通しの良い規模なら全然問題ないと思うけど。
>>175 いやいや、それは子クラスのほうが呼ばれるだろう。
>>176-177 つまり、「何でもかんでも付けるのが悪い」ではなく、「必要なものにだけ付けた方が良い」ということですね。
やっと納得しました。ありがとうございます。
ボクが(基本クラス)これから作る作業内容 後(継承先のクラス)で内容が変えられちゃうかも知れないけど どんなことをするのか仮組み(仮想関数)しておくね。 でも、弄る時はちゃんと読んで(コンストラクタして)から弄ってね。 みんな、ボクの手順に従うなら覚えるまで時間掛かるけど、 覚えちゃえば直ぐ作業にかかれるからね。 もし、君が仮組みを使って好きな様に弄りたいならちゃんと自分で考えてね。 やることが増えちゃうけど、自分好みにできるよ。 こんなかんじ?
>>178 本当だ!
ということは、親クラスのインスタンスを生成してtestMethodを実行しても、virtualが付いてて子クラスで
オーバライドされてると、親クラスのインスタンスでメソッド実行してもオーバライドされてる子クラス側の
メソッドが動いちゃうんだ!
ということは、virtualの動作で気をつけるのは子クラスじゃなくて親クラスの方か?
phpの標準がC++のvirtualで phpのfinalがC++の標準で phpのabstractがC++の純粋仮想関数 ってことかしら
>>181 親クラスのインスタンスなら親クラスのメソッドが動くだろ。
親クラスっぽいけど実は子クラスの時に仮想関数の仕組みが動くんだよ。
#include <iostream>
using namespace std;
class Parent {
public:
virtual void Foo() { cout << "Parent::Foo()" << endl; }
};
class Child : public Parent {
public:
virtual void Foo() { cout << "Child::Foo()" << endl; }
};
int main() {
Parent p; p.Foo();
Child c; c.Foo();
Parent * pp = &c; pp->Foo();
return 0;
}
--output--
Parent::Foo()
Child::Foo()
Child::Foo()
このスレ笑えるわ
#include <iostream> using namespace std; class base1 { base1(); ~base1(){cout<<"base1"<<endl; } class obj1:public base1 { obj1(); ~obj(){cout<<"obj1"<<endl; } class base2 { base2(); virtual ~base2(){cout<<"base2"<<endl; } class obj2:public base2 { obj2(); ~obj2(){cout<<"obj2"<<endl; } int main() { cout <<"非仮想"<<endl; base1 *p1 = new obj1; delete p1; cout <<"仮想"<<endl; base2 *p2 = new obj2; delete p2; return 0; }
↑仮想デストラクタ ↓仮想継承 #include <iostream> using namespace std; class base { protected: int val; public: int getval(){ return val;}; }; class obj1 : virtual public base{}; class obj2 : virtual public base{}; class obj3 : public obj2, obj3 { public: obj3(){ val=100; }; }; int main() { obj3 my; cout << my.getval() << endl; return 0; }
仮想継承まで引き合いに出す意味無いだろ。ポリモーフィズムの 使いどころも良く分かって無い人間が、近年の言語ではC++にしか ない多重継承でのさらに仮想継承まで知る必要ねーよ。
仮想関数として宣言すると、派生先で継承と
仮想関数のオーバーライドが出来るようになる。
このため、基本クラスの派生クラスでは、
実装内容だけが異なる、全く同じ形式の仮想関数を持つことが出来る。
これにより、基本クラスとその派生クラスでは、共通インターフェースを持つことが出来る。
>>187-188 標準C++言語辞典柏原正三(著) より抜粋簡略
という事らしい
親クラスの参照を引数にとって そいつのメソッド動かす関数 a を作った その関数に小クラスを渡した 関数 a は virtual 付きメソッドなら 小クラス側を実行し virtual 無しメソッドなら 親クラス側を実行する
そんな動きするんだ。 C++ってなんかすげえね。勉強しよかなw
Mac OS XでC&C++のプログラミングをし、それをWindows XPで実行したいと思っています。 1. Windowsで動かす際に、スクリプトをどのように変更すれば良いですか? それとも基本的な仕様から違いますか? 2. Windowsのコンパイラは持っていないのですが、手に入れるのは容易ですか? 3. Windowsで動かす際、exe(実行)ファイルにして誰でも扱えるようにすることは可能ですか? よろしくお願いします
1.スクリプトの問題ではない。 仕様違いのためほぼ無理。 クロスコンパイラーでもあれば別 2.容易 3.同じwindows環境であれば。
迅速な回答ありがたうございます 仕様違うんですね……書き方が似てる程度でしたか ちょっとWindowsのほうも勉強してみます
>>192 C言語完璧にしてからのほうがいい。完璧ってのはどのくらいか?
というと
・コンパイル結果のアセンブラがどんなプロセッサでもなんとなく読めるようになること。
・C言語で色々やっていて「こういうところは言語が自動化してくれたら楽だなあ」とか思えるようになること。
C++は「こういうところは言語が自動化してくれたら…」をやってくれた言語なので、
つまずくことが減る。いきなりC++やっても上に何人もいるvirtualの使いどころが
分からない人間になるのが落ち。
挙動を言葉で知っていても、使いどころが分からないので、とりあえず
全部つけとけ、ということになる。
余談だが、Javaをいきなりやるのは有りだと思う。Javaは全部virtualだから。それが
どういうことか分かるだろ? いきなりやった人間が区別できないのは目に見えてる
から、機能的に無いと困るvirtualで統一したんだよ。
ソースコードの仕様は言語によって決まってるだけだから別に変わらんよ。 スクリプトがソースコードをさしているのなら、OS固有のAPI使ってない限り、 その環境でコンパイルすれば動く
>>196 C Perl PHP JavaScript C#あたりをやったことあって、C++の挙動がおもしろそうだなあと思っただけなんだけど
アセンブラ読めないと手をつけないと駄目ですか
補足で、親クラスの参照からメソッドを呼び出すときに、親、子のどちらのものが呼ばれるかが 言語で決められているわけではなく、実装により変えられるところがおもしろそうだなあと思ったとこです。
>>197 恐らくソースコードの事です。スクリプトだと意味が違ってしまうんですね…。
ありがとうございます、C言語にC++が少しだけ入ってる程度なんでちょっとWindowsでそのままコンパイルしてみます
>>198 >C++の挙動がおもしろそうだなあ
これがもし、Cやってて「こうだったらいいのになあ」と思ったことに
結びついてるならC++やる資格あると思うよ。
アセンブラに関しては、概要を知っておけば、C++の挙動が
どうしてこうなるのか、というのが直接覗けるので、virtualを
全部つけとけばいい、みたいなことを考えなくて済むようになる。
>>198-199 C#を知っててなぜそういう感想になるw
C#は親側でvirtual, 子側でoverrideを指定するとポリモーフィックになる
そうでなければメソッド呼び出しは静的に解決される
子側の指定も必要なのがC++よりキツいが、基本的に同じだろ
>>199 >おもしろそうだなあ
面白いかどうかよりも、プログラムする上で必要かどうかじゃないか。
プログラムが趣味で言語オタクとしてそれを楽しむというなら、
本末転倒は承知の上でそれもアリだがな。
>>202 ごめんwC#もっと勉強してから出直すwww
>>202 便乗質問なんだけど、親のvirtual指定を子側でキャンセル(あえてoverrideしない)できるということ?
>>203 俺はそうは思わない
BASICやCOBOLだけやってて、オブジェクト指向や関数型の言語に触れたことの無い人は
普通は言語に思考を規定されることになる
知的好奇心や向上心を失ったプログラマは、あっという間に老害化するだけだ
が、C++は勧めないな、俺は
>>205 そういうことになるね
キャンセルというよりは
C#だと
親のvirtualは「オーバーライドしていいよ」
子のoverrideは「オーバーライドします」
ってことだな
C++的発想だと、virtualであると言った時点でvtbl作らないといかんわけだし
無駄に見えるけどな
>>207 選択肢が増えるのがいいことなのか、親がvirtualしろといってるのに
しないってのはどうかと思うが。
まあC++の場合は親のポインタから呼び出すときでも、強制的に
静的に呼び出せるから、同じといっちゃあ同じだがね。vtblは
確かに無駄になる。
209 :
デフォルトの名無しさん :2008/07/09(水) 11:22:01
>>196 何言ってんのお前。
低位の動作は隠蔽して、より使いやすくするために高級プログラミング言語が生まれたんだろ。
アセンブラやCを学んで悪いことは無いが、学ばなきゃいけない、なんてバカげてる。
そんなものはつまずいた時に初めて、関係あるところだけ目を通せばいいんだよ。
いや、それすら普通は必要ないだろうな。「C++の勉強」をしていれば、C++は使えるようになる。
virtualの件だって、最初は全部に付けてたっていいじゃないか。
それで何か問題が起きて初めて、これは変だと気付けばいいだけの話だろ。
最初から全て理解した上でなきゃ何もしてはならない、なんてのは最低の勉強方法だ。
何事も好奇心ですよね
>最初は全部に付けてたっていいじゃないか 他人への迷惑とかは考えないのか?
Cなんかやらなくても、いきなりC++で平気だよ。 > いきなりC++やっても上に何人もいるvirtualの使いどころが > 分からない人間になるのが落ち。 「C++をやる」っていうのは、C++を勉強し使えるようになることも含むのであって、 「virtualの使いどころが分からない」人間は、単に「ちゃんとC++をやってない人間」だよ。 「先にCをやっていないから」そうなるのではなく、「C++をちゃんと勉強していないから」そうなるだけ。
>virtualの件だって、最初は全部に付けてたっていいじゃないか。 >それで何か問題が起きて初めて、これは変だと気付けばいいだけの話だろ。 そういう姿勢だったら問題は無かっただろう。
ていうか、Cを先にやっておかないと全部virtual付けるようになる、っていうこと自体が、 いったいどこで仕入れてきたフォークロアなのかようわからんよね。
>>211 まずそんな初心者に勝手に組ませて、いざ失敗されると「迷惑だ」と怒り出す方が頭おかしい
>>215 おま…、一人だけで組んでるのか? 社会に出ろよ
別にプログラミングで社会に出る必要はないと思う…
そもそもなぜ全部にvirtualをつけようって発想になるんだろう? そうすることが悪いとは言わない(後から学べばいいと思う方)けど、そうした方がよさそうに思う理由が知りたい
集団における作業、という設定を強調するなら、そもそも全部にvirtual云々というのは 「新人にそういう乱暴な教え方をする奴っているよなぁ」みたいな問題であって、 他言語の経験とかそういう話とは違ってくるのでは。
220 :
デフォルトの名無しさん :2008/07/09(水) 11:43:58
>>218 気が向いたらオーバーライドできるし、しなくても普通に使える。柔軟性アップじゃね?
>柔軟性アップじゃね? そのとき効率の犠牲が気にならないならC++じゃなくてもいい
>>220 子クラスの同一名メソッドは、無条件にオーバーライドされる。
しなくても普通に使える訳ではない。
必ず違うメソッド名にする必要がある。正直迷惑。
勉強で書いてるうちから効率のこと気にしてたら汚いコードしかかけなくなるw
>>212 >「先にCをやっていないから」そうなるのではなく、「C++をちゃんと勉強していないから」そうなるだけ。
いややはりCを先にやっとけ。C/C++の関係なら時間もそんなに無駄にはならん。
他の言語やるまえにCやれってのとは事情が違う。
225 :
デフォルトの名無しさん :2008/07/09(水) 11:53:56
>>221 趣味の場合は効率はあまり気にしないな
>>222 ん?virtualを付けないと、子クラスで定義しても親クラスの関数が使われちゃうんだろ?
つまり子クラスの定義が無駄になると。そんな状況に何の意味があるのさ。
C++勉強しなおしたら?
>>224 殆ど無駄にならんっていうか、無駄はそもそも無いのでは。
ごく少数の例外事項を除いて、C++の中にCはすっぽり入ってるわけだし。
この話はつまり、
「C++の(Cに対する)拡張部分を脇にのけて、残った部分からやるという分類行為に
"物凄く意識的になる"必要があるのだろうか?」
って話で、俺はそこまで必要とは思わない、って意見。
Cの存在を無視して、C++という一個の言語だけ見つめても、それを「基礎から」学んでいこうと思えば
序盤はまぁ大体がCにもある機能の話になる。自然に。
virtual以前に、クラスの作り方自体、どの本を見ても、Cの機能を一通りやったあと触れることになるし。
その「自然にそうなる程度の区分け」で十分ではないかと。
>>225 >>226 >>227 ほらー、virtualつけたときのコンパイル後のイメージが分からないから
そういうことになるんだよ。
>>229 >「自然にそうなる程度の区分け」
それプラスやはりコンパイル後のイメージに興味持って欲しいね、俺は。
ポインタとメモリの関係が分からない人間にポインタ扱わせるのは危なっかしくて
しょうがないだろ。C++は全般的にそういう傾向があるとおもう。
231 :
デフォルトの名無しさん :2008/07/09(水) 12:36:21
質問なんですがC言語で 任意の1〜9の数の全ての組み合わせを表示する、 例えば1〜3の組み合わせだと123、132、213、231、312、321と表示するプログラムの考え方を教えてください。
>>231 プログラムが書ける上でその質問してるのか?
>>231 for(i = 111111111; i <= 99999999; i++) {
if (i にゼロが含まれている) {
/* 何もしない */
} else if (i に同じ数字が2つ含まれている) {
/* 何もしない */
} else {
/* i を表示 */
}
}
>>233 それ順列だろ。
>>231 の文には矛盾が有る。
3行目は組合せと言いながら順列を出している。
>>225 の何がおかしいのかわからん。
お前ら批判する前にちゃんと理由を言えよ。
virtualとオーバーライドをごっちゃにしてる奴がいるな。無関係じゃないが別物だぞ。
virtualが付いて無い → オーバーライド禁止 デストラクタにすらvirtualが付いて無い → 継承禁止 が基本だと思ってたけど違うの?
>>237 >virtualが付いて無い → オーバーライド禁止
単に派生クラス側で基底クラスのメソッドと同じ引数を持つメソッドを
定義することをオーバーライドといい、virtualがついているかどうか
は関係が無い。
>デストラクタにすらvirtualが付いて無い → 継承禁止
別に禁止されてるわけじゃない。そうした方がよけりゃ
そうするだけ。
>>235 > virtualを付けないと(中略)子クラスの定義が無駄になる
この辺がおかしいのでは
240 :
デフォルトの名無しさん :2008/07/09(水) 14:07:49
>>233 お答えありがとうございます。
俺の文章がわかりにくくてすいません。実装したいプログラムとちょっと違うけど、考え方は一緒だったのでわかりました。
礼儀のなってない香具師の教育の場になりますた。
お前が言うなw
お子様相手に頑張ってる皆様にお礼_言いなさい!
>>238 動作を上書きしなきゃオーバーライドにならない気がするんだが、
virtualつけなくてもできるのか?
>>244 小クラスのインスタンスを小クラスのまま呼び出す場合 はちゃんとオーバーライドされてるじゃん
class Child cInstance;
cInstance.hogehoge();
多態しないならvirtualいらない。 多態はしなくても継承・オーバーライドをすることはある。
>>238 >>245 >単に派生クラス側で基底クラスのメソッドと
>同じ引数を持つメソッドを
>定義することをオーバーライドといい
それは「隠蔽」と言う。
以下で A::f2()からのf1()は、常にA::f1()が呼ばれる。
struct A{
int f1(){return 10;}
int f2(){return f1()*2;}
};
struct B : A{
int f1(){return 100;}
};
void test(){
B b;
std::cout << b.f1() << ":" << b.f2() << std::endl;
}
--結果-----
100:20
>>デストラクタにすらvirtualが
>別に禁止されてるわけじゃない。
使い方によって、リソースリークの危険が大きくなるため
通常は継承不可と捉えるべき。
>>247 struct A{ int f1(){return 10;} };
struct B : A { int f1(){return 100;} };
void test(){
A a;
B b;
std::cout << a.f1() << ":" << b.f1() << std::endl;
}
--結果-----
10:100
こっちは オーバーライドって言わない?
249 :
デフォルトの名無しさん :2008/07/09(水) 15:16:19
すみません質問です。 以下のコードを実行すると、 ifstream fs; fs.open( "hogehoge", ios::in | ios::binary ); fs.is_open()がfalse、fs.rdstate()の結果が0x2(failbit)となります。 ifstreamがコケる原因は全く思いつかないのですが、他に何かありますでしょうか? 環境はWindowsXPSP3、VisualStudio2008Stdです。 いくつか検証してみたところ、下記の現象も見つけました。 ・"hogehoge"は確実に存在する(boostのexists()でtrueが戻る) ・"hogehoge"は排他制御はかかっていない(手動でリネームも出来る) ・試しにfopen( "hogehoge", "r" )した結果、NULL以外の値が戻る(→成功している?) どうかよろしくお願いします。
>>248 こっちというか、それを説明したつもりだったんだけど、
それを隠蔽と呼ぶ。
オーバーライド 関数名、仮引数の型と構成、戻り値の型が完全に一致しているもの オーバーロード 仮引数の型と構成の異なる同じ名前の関数を多重定義すること
253 :
251 :2008/07/09(水) 15:35:11
ちなみにC#ではオーバーライド時にはoverride、 隠蔽時にはnewキーワードを指定する。 javaではインスタンスメソッドが全て仮想なので、 隠蔽となるのはstaticメソッドのみ。
>>252 >オーバーライド
>関数名、仮引数の型と構成、戻り値の型が完全に一致しているもの
これによって基底の宣言が隠蔽されるのは当然だが、この条件に加え、
さらに基底の宣言にvirtualがないとオーバーライドとは言わないのか?
failbit 回復可能な書式エラーまたは変換エラー
>基底の宣言にvirtualがないとオーバーライドとは言わないのか? 言わないのではないかと勝手に補足する。yes 仮想関数のオーバーライド 基本クラスでvirtual指定した関数を派生先クラスで上書きし 関数名、仮引数の型と構成、戻り値の型が完全に一致させたもの
基底の動作を上書き(オーバーライド)しないと 一致してるだけじゃ駄目だろ。一致してないと上書きできないけど。
ちゃんと書いてあるだろ
およ?ってことは、virtualが指定されていると、子クラスのインスタンスを使って 親で定義されているメソッドを呼び出すことは出来なくなるってこと? 本読むなり調べるなり手段はいくらでもあるけどせっかくなのでこちらで聞いてみますです。
>>257 補足dクス
あと、
>>252 に戻り値の型が完全に一致とあるけど、
C++は共変性に対応してるので、
戻り値の型は同一でなくとも良い。
struct ValBase{};
struct ValDev : ValBase{};
struct A{
virtual ~A(){}
virtual ValBase* f1(){return (ValBase*)1;}
};
struct B : A{
ValDev* f1(){return (ValDev*)2;}
};
void test(){
A* a = new B();
std::cout << a->f1() << std::endl;
delete a;
}
--結果------
00000002
>>260 一応、強引に呼ぶことは出来るけど。
std::cout << a->A::f1() << std::endl;
>>261 正直俺にはよく分からないけど
それはValDevがラップされてValBaseと同じ型扱いをされてるんじゃ?
>>263 つまりはそういうこと。
オーバーライドの際に、
戻り値に、元より具体的な型を指定しても矛盾しない、
このオーバーライドを認めることを共変性といい、
引数に、元より抽象的な型を指定しても矛盾しない、
このオーバーライドを認めることを反変性という。
C++は反変性に対応してないけど。
C++初心者です エラーメッセージが出てきたんですが、エラー元のファイルを見つけられません・・・ 環境はVista、VS2008です エラーが起きたファイルのパス (まず、これがどこを指しているのかわかりません) File : f: \dd\vctools\vc7libs\ship\atlmfc\src\mfc\winocc.cpp VS内の検索でwinocc.cppを検索したのですが すべて検索 "winocc.cpp", サブ フォルダ, 検索結果 1, "Visual C++ インクルード ディレクトリ" 一致した行: 0 一致したファイル: 0 と、返ってきました・・・ どなたか予測が付けられる方がいたら、アドバイスお願いします・・・。 自分でもよく理解できていないんで、何か必要な情報があったら、教えて下さい。 ちなみにデバッグ実行で辿った所、memset.asm内で落ちてるみたいなのですが、さっぱり意味がわかりません・・・
>>266 エラーはライブラリで起きてる。
ソースインストールして中見るでもいいが、通常は
止まったとこからスタックダンプ(呼び出し履歴だっけ?)で自分のコードの該当箇所探して
渡してる引数の値とかチェックしてみ。
>>267 了解です、詳しく値をチェックしてみます
ありがとうございました。
↓newの投げるエラーがキャッチできません!なんでんでしょうか? #include <iostream> #include <new.h> class test{ int *array; public: test(int x); ~test(){delete [] array;}; }; test::test(int x = 1){ try{ array = new int[x]; }catch(bad_alloc&){ std::cout << "bad_alloc" << std::endl; abort(); } }; int main(){ test *a; while(1) a = new test; return 0; } ↓実行結果 Abnormal program termination
本当にbad_allocが投げられているかどうか確認してみなされ
↓だとうまくいくのでbad_allocはでてるはずです #include <iostream> #include <new.h> int main(){ int *array; while(1){ try{ array = new int[10000]; } catch(bad_alloc&) { std::cout << "bad_alloc!!!" << std::endl; abort(); } } return 0; } 実行結果 bad_alloc!!! Abnormal program termination
while(1) a = new test; の部分で、int *array; の為のメモリを確保する部分で先にbad_allocが投げられてるんだと思う。
>>272 try{
test *a;
while(1) a = new test;
}
catch(bad_alloc&){
std::cout << "!!!!" << std::endl;
}
に変えてみたけど、Abnormal program termination と表示されるだけで!!!!は出力されませんでした・・・
何がなんだかわかんねー #include <iostream> #include <new.h> int main(){ int *array; while(1){ try{ array = new int[7]; // <-確保する量を減らしたらcatchできなくなった、8以上だとcatchできる } catch(bad_alloc&) { std::cout << "bad_alloc!!!" << std::endl; abort(); } } return 0; } 実行結果 Abnormal program termination
あーわかった。たぶん
276 :
デフォルトの名無しさん :2008/07/09(水) 19:44:12
なんか違う例外も発生してるのかも? catch(...) も追加してみたらどうなるだろう
ほかのエラーもキャッチできませんでした #include <iostream> #include <new.h> int main(){ try{ int *array; while(1){ array = new int[4]; } } catch(bad_alloc&) { std::cout << "bad_alloc!!!" << std::endl; abort(); } catch(...) { std::cout << "not bad_alloc!!!" << std::endl; } return 0; } 実行結果 Abnormal program termination
>>276 ぱっと見た感じ、ステレオの場合にファイルからの読み込み回数が
増えるようになってたので、そこが遅さの原因かも?
wave.cの Sound *Read_Wave(char *filename) のファイル読み込み部分を、
ファイル全体を一度メモリに読み込んでから処理するように変えれば、
いくらか速くなる・・・かも。
構造体の配列にに一気に読みこんでも大丈夫そうだけどな
284 :
デフォルトの名無しさん :2008/07/09(水) 20:25:41
>>280 なるほど。しかしそんなスキルがありません\\
>>279 魅上!何をしている!?助けろ!!書けー!
じゃあ、どんなスキルを持っているんだ?
>>284 じゃぁ何か?最初から、「もっと速いのを俺の為に書け」と、
そういうつもりで書き込んでたのか?
>>286 身の程も弁えず赤の他人に丸投げする厚顔無恥のスキルとか。
>>278 // MinGW g++(GCC)3.4.5 にて
// bad_alloc!!! が出力されたよ
#include <iostream>
#include <new>
int main(){
try{
int *array;
while(1){
array = new int[4];
}
}
catch(std::bad_alloc&)
{
std::cout << "bad_alloc!!!" << std::endl; // 可能性としてはここでメモリ確保失敗?
abort();
}
catch(...)
{
std::cout << "not bad_alloc!!!" << std::endl;
}
return 0;
}
特技はイオナズンとありますが?
>>289 BCCが悪いのかな?
MinGWっていうの使ってみますわ
>>285 わるいわるい、席外してた。
メモリ確保できなくて例外が飛んだとき、std::coutが動作できるほどメモリがあまってないんじゃないのか?
メモリ確保の一回の単位を大きくすると、最後の失敗で返却される余裕が大きいから、std::coutが動く余裕ができる、と。
ま、良そうだから分からんけど。
catchが起きてるかどうかは表示じゃなくてブレークポイント貼るとかしてみたら?
とおもったら
>>289 が書いてるじゃん
>>291 はい、スレ住人のSAN値にダメージを与えられます。
>>293 そういうことかーーーーーわかりやすい説明dd
>>295 どこの環境の所為というよりも、メモリ確保失敗ではありがちなシチュエーション。
こういうのを、スッと予想できるようになったら初心者脱出だよ。
決してプログラミング言語の全貌理解するとか、機能や仕組みの名称を
間違えずにいえるとかは関係ないんだな。
std::coutでなくてstd::clogに出力してみれば? そういう問題でもない気もするけど。 ちなみにBCC5.9.4ではunknown software exceptionの ダイアログボックスが表示される。
299 :
デフォルトの名無しさん :2008/07/09(水) 21:10:17
main関数内で宣言して値を入力した配列を関数に渡すにはどうしたらいいですか? ポインタが絡むと良く分からなくなります
>>299 ポインタを勉強してみるとか
STL vector を参照渡ししてみるとか
qsortの引数とかで使われている関数へのポインタというのが 良く分かりません。 変数や構造体のポインタというのは、それがメモリ上で占める 大きさがきっちり決まっているものだと思うのですが、それとは 性質が違うものなんでしょうか? 名前は同じでも。 上の例でいうと、比較用の関数を書きますが、その引数とか渡す タイミングが(qsortの引数にあると)良くわからないのですが。 この辺り詳しく解説していある入門書とかありますか?
↓でようやく狙い通りのbad_allocがでますた。みんなありがとー! #include <iostream> #include <new> int main(){ int *array; char *dummy = new char[0xff]; try{ while(1){ array = new int[1]; } } catch(std::bad_alloc&){ delete [] dummy; std::cout << "bad_alloc" << std::endl; abort(); } return 0; }
>>303 それ自力で思いついたのなら、君素質あるかも
俺がやったとして100%その答えを出せる自信は無いな、情けないけど…。
俺もその発想は無かったわ。 コロンブスだね
Windows Mobile 6で、ファイルの入出力をやりたいんですけど、何の関数を使っていいかわからないです。 環境としては、VS2005、MFCでダイアログベースで、 コントロールの状態について、読み出し・保存を、ファイルで管理したいです。 とりあえず1行ずつ読み出しがしたかったので、 CStdioFileでやってみたら、文字化け…。(ブレークポイント設定して、ウォッチの状態で) CFileだと、一行ずつっていうのがどうしたらいいのかわからないです。 ほかにもfstreamとかfopenとかいろいろあるみたいなんですけど、どれがなんなのか、どんな設定が必要なのかさっぱりです。 MSDNもざっとはみたんですけど、unicodeがどうとか、そういう記述が見当たらなくて。 やり方or参考になるものを教えていただけませんでしょうか。
1行ずつならCFileの子供にそういうクラスあったはず UNICODEなら_UNICODEって#defineする必要あり っていうか、MFCなのか
>>307 文字化け以前に、バイナリのレベルでは読み出せてるの?
>>308 ど、どれでしょうか・・・(;´Д`)ウウッ…
>>309 馬鹿なこと聞きますが、
バイナリのレベルで読み出せてるかっていうのはどうやって確かめたらいいのでしょう??
おいおい、中身が明らかなファイルを読み出しながら1バイトずつ表示でもしたら? WM6の実行環境がどうなのか俺は知らんけど、あんたそこまで分からん初心者なのか?
CStdioFileだな ていうか、MFCスレで聞いた方が良さ気
>>311 ごめんなさい、そこまでわからん初心者です…。
一応中身はあきらかなファイルを作って見てはいるんですが、1バイトずつ?とかっていうのがわかりません…。
おいてあるファイルの中身は
key=test
の1行だけです。
>>312 一応今はCStdioFileとかの関数を使ってますが、それ以外でも実現可能ならなんでもよかったので、こちらで聞いてみました。
だめでしょうか(´・ω・`)
やってみたのはこれ↓で、lineに中身が入ると「敫㵹整瑳」って感じになってますです。。。 CString m_FileName = path; CStdioFile inFile; if( !inFile.Open( m_FileName, CFile::modeRead ) ){ inFile.Open( m_FileName, CFile::modeCreate ); inFile.WriteString(_T("key=test")); MessageBox(_T("設定ファイルのオープンに失敗しました。")); inFile.Close(); return; } CString line; while(inFile.ReadString(line) != NULL){ MessageBox(line); }
女性?
virtual LPTSTR ReadString( LPTSTR lpsz, UINT nMax ); virtual BOOL ReadString( CString& rString ); 戻り値 最初の改行文字を読み込んだとき、読み込みを停止します。このとき、読み込んだ文字数が nMax-1 より少ないときは、バッファに改行文字を格納します。いずれの場合でも、null 文字 ('\0') が付加されます。 とりあえず、そのwhile文はやめろw
318 :
307 :2008/07/10(木) 00:00:25
自作クラスから組み込み型への変換したいのですが、 暗黙的変換を禁止し、明示的変換だけ許可する方法はありませんか? C#だとexplicitとimplicitで可能ですけど
320 :
307 :2008/07/10(木) 01:19:53
あれ? よくわからないアクセスエラーが出てきたので、最初から作り直したら、うまくいきました。 なんか、おさわがせしてしまいまして、すみません。。。 変えたところはwhileの条件なので、そこが原因だったのかもしれないです。 どうもありがとうございましたm(_ _)m 結局動いたコードは↓です。 CString m_FileName = path; CStdioFile inFile; if( !inFile.Open( m_FileName, CFile::modeRead ) ){ inFile.Open( m_FileName, CFile::modeCreate | CFile::modeWrite ); inFile.WriteString(_T("key=test")); MessageBox(_T("設定ファイルのオープンに失敗しました。")); inFile.Close(); return; } CString line; while( inFile.ReadString(line) != FALSE ){ MessageBox(line); }
>>319 それがないんだな。
C++0xでは型変換演算子にもexplicitつけられるようになる予定。
322 :
319 :2008/07/10(木) 01:46:26
>>321 ないですか…。ありがとうございます
C++0xマダー?
VC++ 2008が対応してくれると信じて
323 :
デフォルトの名無しさん :2008/07/10(木) 10:38:06
>>319 明示的にやるなら変換関数つくって呼ぶだけじゃね?
325 :
デフォルトの名無しさん :2008/07/10(木) 13:13:40
class CHoge { public: CHoge(){ _asm{ mov ecx , m_value xorps xmm0 , xmm0 movaps [ ecx ] , xmm0 } } virtual ~CHoge(); virtual void func(); private: __declspec( align(16) ) float m_value[4]; }; のようなクラスがあったとして、そのインスタンスを ある関数内で自動変数として確保したとき、 m_valueのアドレスが16byte境界でないために movaps のところで 停止してしまうのですが、m_value のアドレスが16byte境界になる ようにする方法はありますでしょうか? できれば movups に変更しないで済む方法でお願いします。 環境:VisualStudio6 + sp5 + ProcessorPack WindowsXP
少し大きめの配列を取って、そこに割り当てる。 char dat[200] CHoge * chp; if((&dat[0] &0x00001) == 1) chp = (CHoge *) &dat[1]; else chp = (CHoge *) &dat[0];
char dat[sizeof(CHoge)+1]; のほうがいいかな
328 :
デフォルトの名無しさん :2008/07/10(木) 13:29:55
>>326 解答ありがとうございます。
クラス宣言側で対処できないものかと考えていたのですが、
もう少し考えてみたいと思います。
クラス生成時に同じことをやればできるのだが。 わかる?
サンプル要る? ちなみに言語的には無いはず
16バイト境界だから、それじゃ全然足りないと思うけど。 char dat[sizeof(CHoge) + 15]; CHoge *chp = (CHoge*)(((uintptr_t)dat + 15) & ~15);
アラインされたヒープを操作するクラス作って、そいつに任せたら? CHoge() の中で _asm{ mov ecx , <ヒープ先頭> xorps xmm0 , xmm0 movaps [ ecx ] , xmm0 } とやらずに済まないかな? と
333 :
デフォルトの名無しさん :2008/07/10(木) 13:34:00
__declspec(align(16)) CHoge hoge; ってことですか?
placement newは?
>>325 ちょっと待て、
mov ecx , m_value ←これ、ecxに&m_valueが入るのか?
337 :
デフォルトの名無しさん :2008/07/10(木) 13:41:05
う〜ん、やっぱりインスタンス作成側で解決するしかないみたいですね。
>>336 m_value が配列だから &m_value[0] に相当する値が ecx に入るんじゃね?
いえ、クラス内で生成時にアライメンと調整が出来ますよ class CH { char dat[200]; // 数は適当 dat * chp; CH() { CH *chp = (CH*)(((uintptr_t)dat + 15) & ~15); } } これでクラス内だけ
340 :
デフォルトの名無しさん :2008/07/10(木) 13:44:46
>>336 すみません。簡略化のためにミスしたようです。
そこは m_value のアドレスが入ると思ってください。
dat *chp = (dat *)(((uintptr_t)dat + 15) & ~15); に訂正
>>338 インラインアセンブラはそこまで気にしてくれない。俺んとこでは先頭要素が入る。
本人分かってるからいいけど。
343 :
デフォルトの名無しさん :2008/07/10(木) 13:52:03
>>339 なるほど。其の方法ならクラス内で吸収できそうですね。
いただいたご意見は参考にさせていただきます。
ありがとうございました。
そこは環境依存上等な部分なんだから、アライメント指定をしておけばいいだけだろ。
なー、アラインメントがんばるより、エラー起きないオペコードにしたほうが速くね? 沢山アクセスするなら分からんが、どうせ一回読んだらxmmの上で転がしまくる んでしょ?
347 :
デフォルトの名無しさん :2008/07/10(木) 14:28:29
できますよ 他の関数の中に書いてもいいです
349 :
デフォルトの名無しさん :2008/07/10(木) 14:35:20
マウスのクリックなどいつ起こるか分からない処理をプロシージャの中に書く。 (今は、マウスがクリックされたときコモンダイアログを出すという処理をしたいとします) マウスがクリックされたら コモンダイアログを開く関数を呼び出す という内容を書く って考え方であってますか?
その文面から読み取れる範囲では合ってる。 まぁ、試せばすぐにわかるさ。
351 :
デフォルトの名無しさん :2008/07/10(木) 14:40:18
そのコモンダイアログを開く関数がうまくかけないんです。。。 引数がよくわからなくて APIのメイン関数は int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int showCmd) って書く。 なにか自作の関数は int WINAPI Hoge(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int showCmd) じゃだめなんですか?
引数は自分で決めればよろしい。 int Hoge() でもいい
わかったかもです。 int WINAPI test(HWND hWnd){ static OPENFILENAME ofn; static TCHAR filename_full[MAX_PATH]; // ファイル名(フルパス)を受け取る領域 static TCHAR filename[MAX_PATH]; // ZeroMemory( &ofn, sizeof(ofn) ); // 最初にゼロクリアしておく ofn.lStructSize = sizeof(ofn); // 構造体のサイズ ofn.hwndOwner = hWnd; // コモンダイアログの親ウィンドウハンドル ofn.lpstrFilter = _T("text(*.txt)\0*.txt\0All files(*.*)\0*.*\0\0"); // ファイルの種類 ofn.lpstrFile = filename_full; // 選択されたファイル名(フルパス)を受け取る変数のアドレス ofn.lpstrFileTitle = filename; // 選択されたファイル名を受け取る変数のアドレス ofn.nMaxFile = sizeof(filename_full); // lpstrFileに指定した変数のサイズ ofn.nMaxFileTitle = sizeof(filename); // lpstrFileTitleに指定した変数のサイズ ofn.Flags = OFN_FILEMUSTEXIST; // フラグ指定 ofn.lpstrTitle = _T("ファイルを開く"); // コモンダイアログのキャプション ofn.lpstrDefExt = _T("wav"); // デフォルトのファイルの種類 // ファイルを開くコモンダイアログを作成 if( !GetOpenFileName( &ofn ) ) { MessageBox( hWnd, _T("エラー"), _T("エラー"), MB_OK ); SendMessage( hWnd, WM_CLOSE, 0, 0 ); return 0; } // 選択されたファイル名を表示 MessageBox( hWnd, filename_full, _T("OK"), MB_OK ); return 0; } としてプロシージャ内でtest(hWnd)で呼び出せばOKすか?一応うまく動作しました。
いいけど、それじゃファイル選択しないでキャンセル押したら元のウィンドウも閉じるんじゃ
>>354 そうですね。サイトのプログラムがそういう仕様です。
hWndって奴の役割がイマイチ理解できないです
引数で渡さないといけないものですか?
test関数で引数として与えたのは関数内に
MessageBox( hWnd, _T("エラー"), _T("エラー"), MB_OK );
があったからなんですが
staticがヤバい
>>355 ファイル選択のダイアログはモーダルで動作しないと困るでしょ?
モーダルにするには、動作中無効にする親ウィンドウが必要なのさ。
ってモードレスでもダイアログとして動作させるには親がいるけどな。 コモンダイアログで単体で動作することって無さそうだしな。
>>355 >hWnd
fopenで使うFILE* fpと同じだと思っておけばいい。
#include <iostream> int main() { char text[] = "つれずれ"; std::cout << text[1] << '\n'; } こんな感じのプログラムがあるのですが、文字化けしてしまいます。 どう対処すればいいでしょうか。この例では「れ」を表示させたい。
362 :
デフォルトの名無しさん :2008/07/10(木) 19:19:48
あるクラスAがあったとして、 A a(); とした時に出来るaって何物ですか? 引数付きコンストラクタの場合には初期化出来るのに、 上記の場合が駄目なのは仕様上の問題でしょうか?
あ、事故解決・・・ 関数のプロトタイプと被るのか・・・orz
>>362 aは、クラスAを返り値とする引数を取らない関数の宣言。
>>361 std::cout << text[2] << text[3] << '\n';
>>361 ×つれずれ
○つれづれ
くつずれじゃないんだからさぁ……
368 :
361 :2008/07/10(木) 20:45:20
なるほど。連続で出力すればよかったんですね。 解決しました。ありがとう
文字コードとか考えてるか?
rand()を使って0-9の乱数を発生したい場合、ある本で、rand() % 10で剰余を取ればいいとあったのですが、 元のrand()で発生するのは(自分の処理系では) 0-7FFFとなるので、0-9の出現確率が1/10にはならない はずです。 また%は計算コストが掛かると思うのですが、計算コストが少なくかつ精度良く任意の範囲の乱数を計算す る定石ってあるのでしょうか?
>0-9の出現確率が1/10にはならない はずです。 なぜそう思った?
(int)((10 * rand())/(RAND_MAX + 1)) とか?
>>370 % のコストなんて気にしないっていう手があるw
あと、出現確率が気になる場合は
rand()>=(RAND_MAX+1-(RAND_MAX+1)%10)
の時にもう一度サイコロを振る
>>374 抜けてたw
RAND_MAX によってはラップアラウンドの問題があるね
int 32bit
RAND_MAX 32767
で考えてた
思うんだが、どんな計算しても
>>370 は「出現確率が1/10にはならないはずです。 」
と思うんだが、いかがなものだろう? 難しい計算のすれば納得するものなのか?
まあ六面体ダイスの出目をmodulo4で剰余取るとかよりはマシだろうが 一般にrand()で使われてる線形合同法は低位ビットの質が特に糞らしいから そういう意味では単に剰余取るのはやはりオススメはできんな ま、ぐぐればいくらでも情報は入ると思うぜ
>>377 了解した。解消の方法はいくつかあるが、%よりは遅そうだな。
解答は他の人にまかす。
>>371 元の乱数が1-10とか1-100とか10の倍数でないと、モジュロの0-9出現回数は1/10
にはならんのじゃないか?
あれ、違うか・・・?
380 :
373 :2008/07/11(金) 00:03:14
>>373 の内容
偏りに関与する部分を使用しないことにする方針
#include<stdio.h>
#include<stdlib.h>
#define KIND_NUM 10
int main(void){
int i, x, count[KIND_NUM]={0};
for(i=0;i<100000;i++){
while((x=rand())>=(RAND_MAX+1-(RAND_MAX+1)%KIND_NUM)) // 0-32767 のうち 32760-32767 を使用しない
;
count[x%KIND_NUM]++;
}
for(i=0;i<KIND_NUM;i++) printf("%d\n", count[i]);
return 0;
}
無限に続くランダム配列の中から ある一定の時間だけ抜き取れば偏りが生じるのがあたりまえなんじゃないの むしろ均等にばらけてる方が自然からみて偏りが生じてると思うんだが。 というおきまりの考察は置いて於いてsrand()忘れてないだろうな
>>379 それは乱数の性能以下の誤差しかで無いと思われ。
危惧があるなら
>>377 の危惧が正しい。
だから、求めるのは、
>>377 の危惧を解消する方法。
383 :
373 :2008/07/11(金) 00:07:23
今なら線形合同法が使われているか方が少ないと思うが 心配ならメルセンヌツイスターでググればよいかと
ジョーカーを含むトランプ53枚のうちランダムに1枚引いたときに
それがキングである確率は1/4じゃないよねって話。
>>380 のやつはジョーカーだったらもう一回引けばいいよねって方法
あ、1/13ですわ。
確率は簡単な気がしても良く考えないと罠にはまること多し。 しかし381はいっぱしなこと言っているつもりかもしれんが、気の毒な人すぎるな。
彼女ができる確立は1/2、できるかできないかだ
友達以上彼女未満を入れてください!
>>389 できる(10%) できない(85%) 主観のみではできている(5%)
昔は標準乱数は性能が今一だったが、今は改善された?
最近のVC++は低位ビットとやらを捨ててから渡してくれるらしいな
0 と 1 の出現順序に規則性を見出せますか? #include<stdio.h> #include<stdlib.h> int main(void){ int i; for(i=0;i<100;i++) printf("%d", rand()&1); return 0; } rand() の返り値に線形合同法の最下位ビットを使用している場合には 0 のみ 1 のみ 0 と 1 が交互に出現 の3つのうちのいずれかになる問題があります
いちばん簡単なのは真ん中とりか?
no = (rand()
>>16 )%10;
どんな計算をしても、0-10程度では多分有る程度は偏ると思われ。
それ以上気にすると、%の性能どころではなくなるかな。
乱数生成の仕組みがわからん
乱数でググれば、山ほど情報が有る、ぐぐれ
>>396 CPUの中にラジウムの入った微細なガラス管があり、そこから放出される放射線
ノイズを元に乱数を発生させている。
CreateFileMapping()でNULLが帰ってくるのですが、 原因が引数にあるファイルネームがフルパスにあるようです。 (相対パスを入力すると問題なかった) OPENFILENAME ofn → GetOpenFileName(&ofn) というにファイルダイアログでファイルパス(フルパス)を取得している のですが、ファイルダイアログから相対パスを得ることはできないでしょうか?
char ss[5]; BYTE bt[5]; for(int t = 0; t < 5; t++) { sprintf(ss[t], "%1u", bt[t]); } fout << ss[0] << ss[1] << ss[2] << ss[3] << ss[4] << '\n'; 'sprintf' : 1 番目の引数を 'char' から 'char *' に変換できません。 というエラーが出るんですが、どうすればいいですか?
sprintfつかうのやめればいいよ
そもそも、確率が6分の1であったとしても 6回サイコロを振ったときに重複した数字がでないか?つったらそうじゃないだろ。 サイコロは、振ったときに6分の1なだけで次に振る時もまた6分の1でしかないんだから。
>>400 std::stringstream使えよ
>>400 for(int t = 0; t < 5; t++)
{
ss[t] = bt[t]; //sprintf(ss[t], "%1u", bt[t]);
}
マジレスすると、ポインタとその中身に関してしっかり勉強した方がいい。
現状では君の知識は、Cを扱うには滅茶苦茶だよ。
ss[t] = '0' + (bt[t] % 10); じゃね?
どーせ宿題
だからこそ動作仕様を満たしつつ提出したら怒られそうなソースをですね
関数ポインタとか使って変態プログラム作るか
>>402 そのとおり。でも何で突然そんなことを?
確率の話してるから言ってみただけかな
>>402 コンピューターにおける乱数の使われ方をよく理解したら。単純にそう言い切れなくなるよ。
乱数の話か擬似乱数の話か区別つけようぜ
乱数ときたら幹
乱馬1/2
>>402 > そもそも、確率が6分の1であったとしても
> 6回サイコロを振ったときに重複した数字がでないか?つったらそうじゃないだろ。
>
> サイコロは、振ったときに6分の1なだけで次に振る時もまた6分の1でしかないんだから。
なんでそんなあたりまえのことわざわざ披露して得意になっているの?
上の書き込みでそれに反することでも書いてあったのかな?
だったら指摘してほしいものだけど。
まあまあ、 高校数学の確率論の話と計算機における擬似乱数列特有の問題を ごっちゃにしてるってか 単に話についてけない人が口を挟みたがってるだけなので スルー汁
>>412 普通のCPUは中にラジウムの入った微細なガラス管があり、そこから放出される放射線ノイズを元に乱数を発生させている。
だから疑似乱数の話は必要ない。
最初の質問者そっちのけで議論はじめんなよw
質問です。 VC2008で新規プロジェクト>「Windowsアプリケーション」で「空のプロジェクト」をOFF とすると、ウインドウが出るだけのソースができあがりますよね。 これを単にDebugコンパイルし、デバッグモード走るらせます。 するとウインドウ右上の×を押して閉じた時、 >test.exe の 0x77d0f48f で初回の例外が発生しました: 0xC0000005: 場所 0x2604b974 を読み込み中にアクセス違反が発生しました。 というログが出力されました。 不思議に思い、デバッガの例外時ブレークを全てONにし試したところ、 DefWindowProc(hWnd, message, wParam, lParam); のところで例外を投げていました。 不審に思い、今まで長年作ってきたプロジェクトから適当に抽出してDebugビルド>実行>閉じるをやってみたのですが、全てのプロジェクトで同様に例外を投げていました。 VC6.0で作った(そちらでは例外なんてでてない)プロジェクトを2008で開き、(自動変換を行った後)ビルド〜とやってみましたが、やはり例外を投げています。 この動作は仕様なのでしょうか? それとも私の環境がぶっこわれてしまっているのでしょうか。
420です。 お騒がせしました。 IME Watcherをいう、XPのIMEをタスクバーに隠すフリーツールが悪さをしていたようです。 なんでまったく関係ないのに悪さをしたのかは不明ですが ・VS2008は言語バーをタスクバーにしまってあると動作がおかしくなる ・IME WatcherはIMEをタスクトレイにしまってくれるツール というあたりに何かありそうです。
>>421 スレチだけど、それじゃあ他の全部のプログラムが終了時に例外投げるんじゃないの?
デバッグ実行限定かもしれんが。
だから他のすべてのプロジェクトで同様の例外が発生したんでないの?
>>422 ええ、デバッグ実行限定ですが、あらゆるプロジェクトが例外投げました
素直にMS2003入れ(て、IMEをタスクトレイにしまい)ました;
425 :
デフォルトの名無しさん :2008/07/11(金) 18:59:01
bmpファイルを読み込むプログラムのヘッダーファイルですが 以下の通りのコードをビルドしようとしたところエラー error C2011: 'STRUCT_IMAGE' : 'struct' 型の再定義 error C2011: 'STRUCT_PIXEL' : 'struct' 型の再定義 が出ました。 どこを直せばいいのでしょうか? #include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 typedef unsigned char BYTE; typedef struct STRUCT_IMAGE{ int width,height; int depth; void* pixels; }ImageData; #define PIXELMAX 255 typedef struct STRUCT_PIXEL{ int r,g,b; }Pixel; ImageData* createImage(int width,int height,int depth); void disposeImage(ImageData *img); int readBMPfile(char *fname,ImageData **img); int writeBMPfile(char *fname,ImageData *img); int getPixel(ImageData *img,int x,int y,Pixel *pix); int setPixel(ImageData *img,int x,int y,Pixel *pix);
どっかで同じ名前の何かがあるんじゃないの?
そのヘッダが同じ翻訳単位の中で二回以上インクルードされてるとか。
VC++初心者です 余りに下らない質問ですいません・・・ エディットボックスに変数の追加をして利用したいのですが Valueは使い方が分かるのですが Controlの意味がよく分かりません。 Googleから調べてみたのですが、コレといってピンとくる情報も見つけられず (あまりに理解が無くて、見ても気づいていないのかもしれないです) Controlのニュアンスもつかめていないので、他にどういうキーワードで検索していいかもわからず ここに書き込ませてもらいました。 どなたか、よろしければヒントお願いします。
>>428 >VC++
VC++2008 Express Edition?
>エディットボックス
System.Windows.Forms.TextBox?
CEdit?
>>429 VisualStudio TeamSystem2008 DevelopmentEdition で
MFCアプリケーションのエディットボックス、変数の種類のところはCEditになってます
答え噛み合ってるでしょうか・・・?
初心者が使うバージョンじゃあるまいに…評価版か?
>>431 未経験中途で入った新入社員です、なのでこれは会社のです^^;
>>432 みんな呆れて返答しないみたいだけど、まずMFCの本とかに
一通り目を通したら?
>>433 今はWin32APIを使ったC++プログラミングの勉強をしていたんですが
資料として渡されたソースで、Win32で書かれたクラスの利用側がMFCで書かれていて
それなりに利用側の構造も理解しないと先に進めないので調べていたんです。
なのでMFCの本を購入してっていうのはちょっと・・・
エディットボックス、Control、Value、コントロール変数 等の組み合わせでググったんですが、
参考になるサイトを見つけられなかったため、書きこませて貰いました。
具体的にはCFileDialogでファイルのフルパスを抜き出すって物なんで
Valueを使ってもControlを使っても実装する事はできたんですが
Controlを使った実装方法の意味がいまいち理解できなかったので質問しました。
みなさん呆れていらっしゃったんですね・・・理由は、質問するために渡した情報が少なかったからでしょうか?
それともそんな【初心者歓迎】スレでも質問しちゃいけない程程度の低い質問だったからでしょうか?
よろしければその点だけでも教えていただけると助かります。
どうもありがとうございました。
時間の折り合いがついたら言われたとおりMFCの書籍で勉強したいと思います。
M = 難しいけど F = ふぉんとうに C = 挑戦しちゃうの?
>>433 すいません、解決しました。
ありがとうございました。
>>435 うま・・・くないですね
がんばります
まあ、よく言われることだけど、初心者は免罪符じゃない。 そりゃ、ここは初心者歓迎とあるけどな。
>>437 ちいさな事でつまずいて、そういう時ほど混乱して膨大に時間を無駄にしてしまうので、
知恵を貸してもらえたらと思ったんです。
他人の貴重な時間を奪ってる訳ですから、おっしゃる事はもっともです。
これだけの時間が経過してわかった事は「MFCの本に書いてある」って事だけだったので、
そういった意味でも勉強になりました。
アドバイスありがとうございました。
初心者ですと言えば教えて貰えると思って書き込んで レスが付かなければひがんでで催促して 優しく忠告されたら逆ギレしてってどんだけ甘ちゃんだよ みんなお前の親じゃねーんだよ vipにも書き込んでマルチしやがってクズ野郎
初心者ですけどー、アルゴリズムとかぁデータ中心の考え方まなぶのにぃーいい本おしえてくださぃーっていうかーマジ教えてほしいっス
とりあえず本屋に言って何か買って来い
そんなこと言ったらエロ本買って来ちゃうだろ
>>438 ホントはみんな、答えを知らないか、質問の意味が分からないかのどっちかw
ゲヘヘヘ、ビニール本かってきちまったぜ・・・ 塩化ビニールの化学式格好いいよ! 塩化ビニールの原子モデルサイコーにエロいぜ!
ジブロモエタンの本は? じぶろ萌えたん
>>440 amazonでアルゴリズムの本を探していたら、
いつの間にかアルマジロランをプレイしていた。
金曜日の夜だったはずなのに、月曜日になっていたとかそんなちゃちな(ry
>>439 会話が噛み合わないのでこれ以上話すのは時間の無駄ですね。
ありがとうございました。
>>443 多分、後者ですね・・・もっと全体像を把握して的確に質問する技術を磨きます。
ありがとうございました。
お前向いてないよ
>>447 会社の人間に先ず聞くべきだったかもしれないね。
while(1) cout << "せんせーできませんこたえおしえて!" << endl; programmer.grow();
error:初期化がされていません
>>449 そうですね・・・それは全く持って思います。
極力社内で解決できるように新人同士のネットワークを作る努力などはしているんですが、
上司や先輩に質問ができる環境を作る努力もしていこうと思います。
ありがとうございました。
455 :
429 :2008/07/11(金) 23:47:27
聞くだけ聞いて、ついさっきまでレスしたことすっかり忘れてた。
GetLastError()の値を調べるべし
>>452 違いは、Controlはvalueより複雑なことができるというところ
たとえば状況に応じてEditControlを有効化/無効化するとかしたいなら
Controlでなければ対応できない
テキストを取り出すだけならどちらも同じことができるので使いやすいほうでよい
458 :
429 :2008/07/11(金) 23:53:32
>>430 もう見てなさそうだけど、オンラインのMSDNの中を色々見て回れば良いと思うよ。
459 :
429 :2008/07/12(土) 00:01:08
補足。特にDDX関連。
>>457 なるほど、より複雑な実装ができるんですね。
今回はとりあえずパスを取りだしたら用済みなんで、時間ができたら調べてみます。
自分みたいな素人にもわかりやすい抽象的な説明、ほんとうに助かります。ありがとうございました。
>>458 さっき、FileDialogのクラスからたどっていろいろなクラスの中身を調べてました。
見ても見ても意味がわからなくて、どこに大事な事が乗ってるのかわからなかったんですけど、やっと発見できました!
なかなかMSDNも自分みたいなへっぽこには欲しい情報を探すのがむずかしくて笑
でも、ちょっと今回見つけられたんで、次回からもっと楽に情報を探せると思います。
ありがとうございました。
>>459 あ、こういう機能をDDX(Dialog Data Exchange)って言うんですね!
ほんと、単語を知らないっていうのは調べ物をするのが容易じゃないです。
ありがとうございました、詳しく調べてみます!
461 :
399 :2008/07/12(土) 00:36:20
462 :
デフォルトの名無しさん :2008/07/12(土) 00:49:59
publicで定義されている純粋仮想関数を具象クラスでprivateで定義するのは 何か弊害ありますか? インターフェースを介してでないと呼べないようにしたいのですが。 弊害がない場合このやり方は一般的なのでしょうか?
463 :
399 :2008/07/12(土) 00:55:14
>>456 ファイルの置き場が悪いのかなと思ったら、
Cドライブ直下に置いてもエラーコードは「指定したパスが見つかりません」だとか。
もうよくわからん
\
>>463 状況がみえないのだが、そもそも CreateFileMapping のパラメタに
パス名というのは存在しないのでは?
オブジェクト名というのはあるけど、これはパス名とは違うし
もともと \ は受け付けない仕様のはず
出てきたフルパスをWin+Rに入れてちゃんとファイルが開くか確認すべき
467 :
399 :2008/07/12(土) 01:53:22
>>465 それっぽい
オブジェクト名はパスが適切だと思ったんだけど
\がすっかり盲点だったし、NULLにしたら期待道理に動作もした。
さんきゅー
マルチスレッドを停止させる方法で別スレッド関数内でループさせて、本体でフラグ変数を操作してループを抜けさせて別スレッドを終了させたいんですが、 終了させようとするとハンドルされていない例外、読み込み中にアクセス違反が発生エラーが出るんですが、こういう使い方は無理なんですか?
>>468 可能、別の原因で出てるエラーだろう。
再現性のあるコードをアップできるならしたほうが早いと思うよ。
朝からすいません、スレッド以外で絞って調べて見ます。ありがとう
>>462 俺の近所では一般的ではないみたい。結局のところインタフェースとなる
基底クラスのポインタか参照を用意する手間を厭わなければ何でもできる
ので、期待できるのは、うっかりミスを防止する程度じゃないかな。
あるいは、具象クラスで基底クラスと概念の異なるインタフェースを提供
して、そのクライアントには基底クラスのインタフェースを触らせない
という用途も考えられるけど、これは多重継承使えっていうサインかも。
>>462 インターフェイスしか触らせたくないのなら、具象クラスのコンストラクタをプライベートにして、newできなくして、
ファクトリメソッドみたいので、作るようにすればいいんじゃね?
473 :
デフォルトの名無しさん :2008/07/12(土) 14:18:49
>>471 >>472 ありがとうございます。
インターフェースしか触らせたくなかったらたしかにnewできなくするべきですね。
デザパタのオブザーバパターンのコールバック関数は
継承したクラスでprivateで持たせるのは一般的にどうなのでしょうか?
そのクラスは直接newして使うクラスなのでなるべく関係のない関数は
隠したいです。
>>473 一般的かどうかは知らんが、俺なら callback を private にするな。
インタフェースは最小が気持ちいいしね。混乱・勘違いされるのが嫌なら
「なぜそうするのか」というコメントかメモを残せばいいでしょ。
昔Cは関数呼び出しのとき、値渡しが原則で、参照の時は明示的にやるので 呼び出し側から、呼び出した結果引数の内容が気づかないうちに変更されている 危険がなくて安心、とかいう説明をきいた記憶があるのですが、C++は呼び出し 側から値渡しか参照渡しかわからない書き方ができるので、これは退化じゃない かと思うのですが、違うんでしょうか?
C++は、別にCの進化系言語ではない
>>475 ポインタの値渡しと参照渡しがごっちゃになってる
constをつけておけば値を変更しないことを明示できるからそれを使うべし
というか気づかないうちに変更されてるって関数の説明くらい読めばいいのに
逆に説明の書いてないような怪しい関数は使わない方がいい
478 :
デフォルトの名無しさん :2008/07/12(土) 17:16:01
C++についていけない猿人プログラマがそんなこと言うらしいな
>>477 > というか気づかないうちに変更されてるって関数の説明くらい読めばいいのに
> 逆に説明の書いてないような怪しい関数は使わない方がいい
それはプログラムするときの心構えや良い習慣の問題であって、言語として問題を
起こしにくいつくりになっていれば、それに越したことはないのでは?
そう言っても「C++はそうなってる」わけだしな 嫌ならDでも使えばいいよ。1.X系は仕様確定してるし
481 :
デフォルトの名無しさん :2008/07/12(土) 17:39:28
「C++はそうなっている」で疑問に思わないようじゃ単なる思考停止だろ。 Dとか出してハク付くているつもりか知らんがプログラマとしては大成しないタイプだな。 C++の参照渡しがあの形になっているのは理由がある。 が、入門書とかでswap(a,b)みたいなので、Cに比べて便利になりました、みたいな説明 をしているのがあって、それは確かにバカじゃないかと思う。 呼び出し元をみただけで、変数が変更されるかどうかわかった方が便利だしミスが少な くなるのはあたりまえ。
ポインタが無くなればバグが減って解決ってことですね
ポインタがないと作れないソフトがあるから、非常に困るw
俺良く分からないけど思考停止だ大成しないと言うのは勝手だけども じゃあ言語の文句をここで言っても意味が無いんじゃって思うんだ
ポインタは便利だろ C++になっても結構使うぞ
まぁもっと問うのに適切な場所は色々あると思うが、 まず便所の落書きLVの場所で篩ってみるのも 迷惑度が下がってよいと思うよ。
googleのC++のコーディングルールは、ロジック追えないから、例外禁止だったな。
>>475 引数の値が変わらないことは、
大して重要なことではありません。
char* p = f1();
f2(p);
free(p);
int handle = open();
close(handle);
Cではどのような関数であれ、
pやhandleの値自体が変わらないことは保証されます。
しかし、ポインタの先やその値に関して重大な影響を与えることはあり、
それは関数の仕様を知る以外に方法はありません。
そして、引数の型が参照かどうかを知るのも同様であるため、
退化というような新たな問題が発生したとは言えないのです。
何するか知らない関数呼ぶとか普通ねぇしな
490 :
デフォルトの名無しさん :2008/07/12(土) 18:01:00
>>485 > ポインタは便利だろ
> C++になっても結構使うぞ
バカだなあ。
ポインタ否定しているわけでもないし、C++の参照渡しを否定しているわけでもないぞ。
swap(a,b)みたいなので参照渡しを使うぐらいなら、C流に&a, &bで渡した方が分かり易
に決まってんじゃん。
C++で必要なはデストラクタとかでどうしても必要だからでしょ。
C#でこの問題がどう解決されているかとかも含め、いっぺん調べてみりゃいいのに。
ポインタ・配列が分からない とCを投げる ↓ VBでポインタ使えない・配列の勝手が悪い と投げる
>>490 > C++で必要なはデストラクタとかでどうしても必要だからでしょ。
なんで、自信満々にバカ晒せるんだろう...
自分こそいっぺん調べてみりゃいいのに...
#define swap(a,b) if(&a!=&b){ a^=b; b^=a; a^=b; } 呼び出し元だけじゃマクロか関数か区別のつかない C言語(とC++言語)は駄目駄目ってことですね
分かりやすいかどうかじゃなくって、C++とか外国人が作ったわけで 外国人から見ればこの記述法のやりやすいってだけの話で。 思考停止云々って馬鹿じゃねーの?できる範囲でできうる限りの事をするのがプログラマだろ。 C++で実装できなきゃアセンブラで書くしアセンブラで出来なきゃ0と1ででもプログラム書いてやるよ。 言語仕様の文句をつけてることで大成するんならご勝手にやってれば? 出来ない事があるからこそ、複数の言語扱えるようになればいいだけの話で CにしろC++にしろ前提条件が「プログラマは、すごい人だからミスなんてしないよね!」っていう仕様になってるから クソッタレな馬鹿は文句つけるしかできなくなる
まさにそのとおりだ
C++でポインタ使わずにポリモーフィズムやってみろよ
参照でやればいいんじゃね
参照はハードコーディングになるから用途が限られる
サウンドの同期再生と非同期再生は何が違うんですか?
たぶん、鳴り終わるまで待つのが同期じゃない?
そもそもそれはC/C++とは関係ないよなw
strtok_s関数で「\」を区切り文字とした場合、 「能」を含む文字列を正しく区切れないのですがなぜでしょうか? char buf[1025]= "ほげほげ能ほげほげ"; char *sp, *nexttoken; sp = strtok_s(buf, "\\", &nexttoken); printf("%s\n", sp); このようなコードを実行した場合、「ほげほげ・」と出力されます。 OSはWinXP Pro SP3、コンパイラはVisual Studio 2005 Proです。 Visual Studio関係の更新はWindows Updateからすべて適用してあります。
505 :
503 :2008/07/12(土) 20:58:39
ダメ文字でググればよかったんですね。 ありがとうございます。
ダメ文字からの解決は止めとけ・・・ 内部はwchar_tを使うように。
アクセス制御に関して質問なのですが、ファイル内のstatic変数にアクセスしたいときは以下でよろしいのでしょうか? /* main.c */ #include <stdio.h> #inlcude "main.h" #include "sub.h" static char szName[10]; void main() { strcpy( szName , "TEST" ); showName(); }; const char* getName( ) { return (const char*)szName; } /* main.h */ const char* getName(); /* sub.c */ #include <stdio.h> #include "sub.h" void showName() { printf( "%s\n" , getName() ); } /* sub.h */ void showName();
まず、 「どう考えてもstatic変数を使うべき所だろう」というとき以外は static変数を使うのを止めましょう。
なんかみんなconstとかでえらそうなこと言ってるけど
>>453 には誰も答えられないの?
みんなVCですか。そうですか。
ここはそんなレベルですか。
>>453 変えても関数の外にはなんら影響しないだろ
>>509 単に読まれてないだけだろ。そう怒るな。
>>507 こんな感じで。 ※各ヘッダにはインクルードガードを。
/* app.h */
struct App {
char szName[10];
};
/* main.h */
#inlcude "app.h"
const char* getName(App* app);
/* sub.h */
#inlcude "app.h"
void showName(App* app);
/* main.c */
#include <stdio.h>
#inlcude "main.h"
#include "sub.h"
void main() {
App app;
strcpy( app.szName , "TEST" );
showName(&app);
};
const char* getName(App* app){
return (const char*)app->szName;
}
/* sub.c */
#include <stdio.h>
#inlcude "main.h"
#include "sub.h"
void showName(App* app){
printf( "%s\n" , getName(app) );
}
>>453 >char *const argv[]
こういう引数ってキモイよな。char**の方が読みやすいし。
constつけるなら
const char* const * argv
だな。
const付いてないなら書き換わるかも、と考えた方が良いと思うぜ。
select()のtimeout書き換えみたいな糞実装もあることだし。
>>509 んー、たしかに const char const *argv[] でないのは不思議ですね。
システムコールにはよくあること・・・ WinAPIのCreateProcessも引数のコマンドライン文字列がconstでなく、 しかもマジで書き換えてくる
>>510 ,511,513
煽ってごめんな。ありがとう。
>>511 「関数の外になんら影響しないように」すれば何の問題もないのは確かなんだけど、
なぜそうなってるのか?が疑問なんです。
>>513 の言うとおり書き換わると思ったほうが良いんだろうけど
なぜ書き換わるようにしているのか?
が気になってるといったほうが質問が適切ですね。
select()のtimeout書き換えは確かに糞実装だけどやりたいことはわかるし、
それと似たような理由がexecv()にもあるんですかね?
その関数を考えた人間じゃないからわからない プログラムはその人のアルゴリズムで書かれてるから何をしているかは理解できても どうしてそうなっているかは、その人でなければ理解できん
>>517 アルゴリズムをなぜそうしたかは、確かに書いた人しかわからないけど、
こういうシステムコールのAPIの引数が実装者にしかわからないってありえないと思うんですよね。
何か理由があるんではないか?と思ってしまうのです。
まあその理由が、
・単純にこうしたほうが処理が速いとか実装が楽
レベルなのかもしれませんけど。
manに書いてない以上、理由を知るのは難しいね。 const付け忘れとか、スペルミスとかも普通に残っていくし。
creat w
初心者の素朴な疑問でこんな風に荒れるとはさすがプログラム板だな(w Cだと実引数でfoo( &x )という書き方で参照渡しできるのに、C++だと なぜわざわざ仮引数側でfoo (int& x)なんて書き方をして、呼ぶ側は foo( x )とするんだろう、呼ぶ側でも区別つけた方がいいんじゃない、 というのはなかなかいい質問だと思うんだが。 「C++はそういうものだから仕方ない」は思考停止とまでは呼ばないけ ど、ちょっと笑って、どこか悲しくなったのは確かだなあ。処世術と してはそれが正しいんだろうね。いちいち悩むな、どうせ自分じゃ世界 は変えられない、与えられたものにいちいち疑問を持つな、みたいな 諦念みたいなものが感じられて(w #一つ煽ると、誰もちゃんと説明できないのに笑った。 #初心者歓迎、じゃなくて、初心者しかいないのね(w
// ここまで説明無し
>>489 > 何するか知らない関数呼ぶとか普通ねぇしな
あなたみたいな優秀なプログラマばっかりだったらきっとカプセル化とかprivateメンバと
とかめんどくさいこと考えずにすんだんだろうね。
いや、皮肉じゃなくて。
>>494 > 分かりやすいかどうかじゃなくって、C++とか外国人が作ったわけで
> 外国人から見ればこの記述法のやりやすいってだけの話で。
これ最高だな。爆笑した。
「外国人が作ったから」
俺も次回から全部これで説明することにするよ。
>>525 >>494 はその説明でいいけど、君はどうも使いどころが理解できてなさそうだから
たぶん恥をかくだろうね。
>>522 > Cだと実引数でfoo( &x )という書き方で参照渡しできるのに、C++だと
> なぜわざわざ仮引数側でfoo (int& x)なんて書き方をして、
こんな馬鹿なことを書いちゃう程度の理解力だから、「なかなかいい質問だと思」っちゃったんでしょうね。
C++0xのガーベジコレクションは結論出てないけど、C++/CLIみたいな記述にしてほしいな C++/CLI自体は、歴史の闇に葬っていいけどw
>>527 494はちょっとどうかと思ったけど。
あれって説明なの?
>>528 俺もいい質問だと思うけど何がダメなの?
>>524 どうして、コロンとドットなのかとか考えたか?
コロンとドットは日本語て言う所の、句読点に相当するのよ。
「あなたにとって最適化されたプログラム言語」ではなく広義では外国人が。
狭義では「C++を作った人にとって最適化されたプログラミング言語」なんだよ。
IDがないと、自作自演かもとおもってしまうよn(ry
初めてC++を勉強したら疑問を持つのは悪いことじゃないと思うけどな そんなに許されない質問なのかな>C++の参照 というか何故かわからないので誰か分かりやすく説明して下さい 初心者でスミマセン
意見に意見をぶつけたい人はID無くても気にならないけど、 とにかくただ対立したいだけの困ったちゃんは、誰が書いてるか気になるのかな。
自分で自分の意見に同意して多数派のフリする奴っているからなぁ
えぴすてーめーの本でも読んでろ、アホ自演。 間違いとかじゃくて、C++とか作った人間が自分に適したように作っただけの 話。本当のプログラマは呼び出し側の変数が変わるなんて注意は当然している。 そんなのも理解できないような奴はVBでもやってろ。 そういう仕様だからそれにあわせるのは当然。
ここは初心者にきびしいスレですね
どうだろう、デカイ態度の初心者がいると厳しくなるのは、人として普通だと思われ。
C#は呼び出し側でもref付けて区別しているんだよな。 これはきっとプログラマを信用してないってことなんだろうね。C++は真のプログラマ 向け言語だからいちいちそういう余計なタイプはさせないという点で優れている。 constの複数の意味とかちょっと考えればすぐわかるようなことを区別するのにいち いちプログラマに負担掛けないのがC++のいいところなのにわけのわからないことを 書くからきつい反応されるんだろ。 わかんねえ奴はC#でもJavaでも使ってりゃいいんだよ。
言語には相反する方向性がある。 1つは、コンピューターを効率よく動かそうとする言語(その分プログラマーに負担を) 2つに、プログラマーのミスを少なくしよう、プログラマーに優しくしよう(その分コンピューターに負担を) 1の代表に、アセンブラ、C、Cから継承されたC++ 2にJava、C#、純粋関数型言語等 この二つは、根本的に設計思想が違うのです。
何も知らないから、何から聞けばいいのかわからないのはしょうがないでしょ? 何で聞いたらダメなの?調べろ?どこでどうやって調べればいいかわからないから、 専門的なことを良く知っているあなたに聞いてるんでしょ? 検索しろっていうけど、自分で調べるより知ってる人から教えてもらった方が早いし、 ちゃんとわかるまで繰り返し聞けるじゃん。いざとなったら代わりにやってもらうことも 可能だし。 こっちは何も知らない素人なんだから、わからないのはしょうがないでしょ? ちょっと知ってるからって、素人を馬鹿にしたような言い方は正直ムカツク。 レベルが低いとか、話が通じないとか、単語が分からなくていちいち説明しなきゃ ならないのかよめんどくさいとか、そんなこというけど自分だって最初は何も 知らなかったわけでしょ?態度悪いし感じ悪いね。 確かにこっちは何もわかってないかもしれないけど、一応要望だけは伝えておかなきゃ あとで後悔するのも嫌だし。勝手に何でもかんでもやった挙句、高いお金かけてたら、 いくらなんでも引くって。ある程度の出費は覚悟してるけど、こっちにも限度ってものが あるんだから。 信用してないわけじゃないけど、信用してるから頼んでるんだし。お願いする立場だけど そっちもちゃんと考えてほしい。 そっちがコンピューターに詳しくて、実力もあるってのはちゃんと分ってるから、 別に疑ってないから、ちゃんと性能がよくてお金のかからないパソコンを組んで。 これが素人の言い分です。
バカの壁…
>>543 素人の分際で知らないモノを教えてくれる人にムカツクだの感じ悪いだの大層なご身分だな
>>524 カプセル化もprivateメンバもする、それだけでなく
メンバ関数の説明も書くし、読む
お前はクラス名や関数名、引数名だけで
勝手に仕様を想像して使いそうだけどな
>>543 そんな泣き言を言っている時点で2chに向かないから、もっと大人になってから来ましょう。
543は「素人はこういう言い分で話をする」と言う例でしょ
コピペされたものであると理解できぬ程 住人の判断力を奪うとは何という破壊力。
関数の仕様変えたとき(主に開発途中)に呼び出し側のコード変えなくてすむのが便利だったからとかじゃないの?
553 :
デフォルトの名無しさん :2008/07/13(日) 01:42:19
「言語仕様に文句つけても意味が無い」とよく言われるが、一人でブツブツ愚痴ってるならともかく、 こういう大勢と対話ができる場所で不満を発することには少なからず意味があるだろう。 不満がもっともなものであるならば、それはその言語の弱点であり、弱点を把握することは周りの人間にも有益なこと。 もし不満が筋違いなものであっても、では何故そのような仕様になっているのかという本当の理由を、 詳しい人間に教えてもらえる。その情報もきっと周りの人間にとって有益なものであるはず。 「黙って使ってりゃいい」って、そっちの方が何も生み出さないだろうと。
納得できねーという奴がいるから新しい言語が生まれる 「黙って使ってりゃいい。気に入らなきゃ自分で作れ」って方が何かを生み出しそうでしょ?
> ちゃんと性能がよくてお金のかからないパソコンを組んで。 なぜこの文が入ってるか分からないが、素人が仕事として依頼する場合に 「ちゃんと性能がよくて」を聞きだすのに非常に時間がかかる。そしてその分を請求 項目に含むのは当然では? 要求仕様が明確であればその分浮くのか?という疑問もわくだろうが、その場合、 玄人から見た観点での改善案も出てくるだろうと思うんだ。 メモリは1Gがいい!→512*2の方が速いっすよ。けど拡張性はさがるっす。どうするっすか? みたいな。
>>555 納得と理解を混同している輩にそんな事言われても
なんか意味不明な事言ってしまった
クラスの型変換演算子?ってなんか嫌われてる気がするけど、逆にどういう時なら使うべき?
型変換て全く違う型に?
別な型を一意に扱いたいときとか。 まぁ大抵型変換演算子使わなくても別な方法があると思うが。
で結局C++の参照呼出しが今の形になった理由はなんなの?
過去ログ読め
565 :
デフォルトの名無しさん :2008/07/13(日) 08:51:27
クラスの型変換演算子?
dynamic_castのことか?
具象クラス固有の機能とか使いたい場合など
ダウンキャストで使う
まぁその時点であまり設計的によろしくないのかも
クラスを別な型に???
>>562 は何言ってんの?www
>>553 だったら、次々期C++に入れてもらえるように標準化委員会に送ってくればいいだけの話だろ?
C++勉強するのにいい本があったら教えてください
BOOL flag = 0; BOOL flag2; void CRS232C_TESTDlg::OnBnClickedstart(){ if(flag == 0){ flag = 1; flag2 = 0; AfxBeginThread(drawData::DrawThreadFunction, this, THREAD_PRIORITY_LOWEST); }else{ flag = 0; flag2 = 1; } } extern BOOL flag; extern BOOL flag2; UINT drawData::DrawThreadFunction(LPVOID pParam){ flag2 = 0; while(flag2 == 0){ //処理 } } これがどうしてもスレッドとまりません、どこがおかしいのかブレークポイントを両方につけてゆっくり確認しながら進めると止まるんですが ブレークポイントを入れないとなぜかflag2が1にならないんです。どういうことでしょうか?
もりあがってんなあw
>>563 結構有名な話だが、C++の参照渡しはオーバーロードされた
演算子をすっきりした記述で書くために導入された。
もし参照が無ければ、
operator = なら
a = b; と書くところ(aが変更される)を、 &a = b; とかって書かない
といけなくなるだろ。式としての記述のスマートさを維持するには、
単に「a」と書いてaを変更することが可能なルールが必要だった
んだよ。
通常の関数では参照と値渡しの区別が出来ないので
関数内で値を変更するためには参照は使用すべきではない。
演算子なら式のどの部分が変更されるかというのは、ほとんど
の人が「算数的」なルールを共有しているから問題はおきにくい。
それなら参照は演算子オーバーロードだけに限定すればいいん
じゃないかという声もありそうだが、C++は一貫性、一般化を極力
重んじるから、これだけ特別、というふうにはならなかったようだ。
D&Eに参照渡しの導入経緯はちょこっと記述があったよ。
>>568 プログラム以前の問題だが、
>CRS232C
誰が書いたか分かるような情報をそのまま書いてしまうことが
気にならないのかい?
>>568 原因はわからんけどフラグの変数にvolataileをつけてみるか、それでもだめだったら、
素直に同期オブジェクトを使うとか。
>>570 もう1週間ぐらいこれやってるんでそろそろ恥ずかしくなってきましたw
volataile、同期オブジェクト調べてみます。ありがとうございます。
つづりが間違ってた。 volatile だ。
とりあえずx86系のwindows限定ならvolatileで対処できるはず。 IA-64とか他のOSへの移植とか言い出すともっとややこしくなる。
575 :
困り熊 :2008/07/13(日) 10:47:15
お初にお目にかかります。 4月から大学でC言語を始めたのですが、課題に四苦八苦しています。 どなたか助言していただけると助かります。 課題 文字列検索の関数の作成 形式 char StrStr(char *s1 char *s2) 機能 文字列s1の中で文字列s2と同じ並びの最初の出現に位置づけする。 返却値 文字列が発見できなかった→NULL、発見できた→位置づけられた文字列のポインタ ロジックもいまいち浮かんでこないので手が付けられません。。。
>>575 文字処理のロジックというのは案外地道なもので1文字づつ丹念に調べてゆくのが基本。
回答だけがまるまる欲しいなら宿題スレへ。 ただし先生がスレをチェックしてることがあるから丸写しは要注意な。
578 :
困り熊 ◆JW6hbMJs/s :2008/07/13(日) 11:00:20
>>576 一応、文章に落としてからソースを考える作業を行っているんですが、どうもうまくいきません。
この質問に相応しいスレがあったのでそちらに移動します。
スレ汚してしまい申し訳ありません。
579 :
デフォルトの名無しさん :2008/07/13(日) 11:10:47
C++のtry..catch..構文にfinallyは無いのでしょうか?
文章に落としてるならそれをアップするといいよ。 そういうのはスレ的に全然OK。
C++しかしらないからよくしらんけど 二重のfor文とif文組み合わせりゃいけると思うんだが・・・。
582 :
デフォルトの名無しさん :2008/07/13(日) 11:18:29
分かりやすいかどうかじゃなくって、C++とか外国人が作ったわけで 外国人から見ればこの記述法のやりやすいってだけの話で。 思考停止云々って馬鹿じゃねーの?できる範囲でできうる限りの事をするのがプログラマだろ。 C++で実装できなきゃアセンブラで書くしアセンブラで出来なきゃ0と1ででもプログラム書いてやるよ。 言語仕様の文句をつけてることで大成するんならご勝手にやってれば? 出来ない事があるからこそ、複数の言語扱えるようになればいいだけの話で CにしろC++にしろ前提条件が「プログラマは、すごい人だからミスなんてしないよね!」っていう仕様になってるから クソッタレな馬鹿は文句つけるしかできなくなる
char* StrStr(char *s1 char *s2) { if (*s1 == '\0') return NULL; if (strncmp(s1, s2, strlen(s2) == 0) return s1; return StrStr(s1 + 1, s2); }
休日だね。いい天気だ・・
末尾再帰の最適化をやってくれるコンパイラを探さなくては
>>579 無い。C++では、finallyより優れたRAIIを使う。
つまりはデストラクタ。
stringコンテナの中身をprintfで表示させる方法について #include<stdio.h> #include<string> using namespace std; int main(){ string a; a="test"; printf("%s",a); return 0; } こうすると(null)と表示されてしまいstringの中身が表示できません。 cout使えと言われそうですがライブラリの仕様上使えないのです
591 :
デフォルトの名無しさん :2008/07/13(日) 11:58:19
595 :
デフォルトの名無しさん :2008/07/13(日) 12:05:23
参照についてこれだけのレスがあって、まともな回答は
>>569 のみ。
普段大口叩いてる奴らが実はいかに無能だったかがよくわかるな。
>>595 ありがとうございました。お帰りはあちらです。
>>595 参照が出来た理由を聞いてたの?
>これは退化じゃないかと思うのですが、違うんでしょうか?
という質問だから、退化じゃないよと答えたけど。
C++は何故参照なんて機能を用意したの?って聞いてれば
おそらくは、俺含め何人か答えてたんじゃない?
598 :
597 :2008/07/13(日) 12:30:34
補足。デメリットのこと話してると思ったんで。
599 :
デフォルトの名無しさん :2008/07/13(日) 12:35:10
要するに質問の真意すら汲み取れない読解力false揃いか。 退化だと思ってるからそういう質問が出る、じゃあ退化でないと言うなら理由を聞かねば納得いかない。 その程度の流れもわからないのか。
>>597 > >これは退化じゃないかと思うのですが、違うんでしょうか?
> という質問だから、退化じゃないよと答えたけど。
それって、やりとりに対してその範疇でしか受け答えしない、
典型的な仕事できない人間じゃないかw
わざとやってるんだろうけどなー
>>600 仕事の話と初心者の質問を一緒にされてもね・・・w
あなたが手取り足取り教えてあげてはどうですか?
ちなみに部下の教育では、答え自体は教えずヒントを与えるだけに留めてますが。
>>599 聞くしか能の無い初心者なのに態度でかいんじゃね?
俺は演算子オーバーロードの為だと思ってたけど ていうかC++の設計と進化とかその辺読めよ
604 :
デフォルトの名無しさん :2008/07/13(日) 12:52:19
悔しいからって
>>602 みたいな中身の無い反応は更にアホっぽいぞ^^
3.7 リファレンス
>>601 あなたは自分自身の邪悪さに心が痛む時がありませんか?
キチガイ警報 お前らいい加減レスすんな
読解力falseの意味が分かりません、これは言語の退化ではないでしょうか?
おまえがな。小学生どころか3歳からやり直せ
読解力false ワラタ リアルでもこんな言葉つかってんのかな
そんな感じの芸人居たよなと思って 10分近くググってやっとルー大柴の名前思い出せた あっちはウケ狙いでやってるんだろうけど
>>565 operator T()のことだろう。
わかってなかったの多分お前だけだし、
>>562 はそのものズバリの回答だぞ。
ゲームパッドに対応したゲームを作成したいのですが、 入力したキーやボタンを取得して、対応した処理にディスパッチする基本的コーディング方法を分かり易く解説した おすすめのホームページを教えてください。
ディスパッチって何?
dispatch
いくつカタカナ使ってんだよ
622 :
615 :2008/07/13(日) 16:13:41
>617 >621 処理を振り分けるようなイメージだよ。 C言語ではあまり使わないのかな? ちなみに自分はJavaメインでWeb系システム構築時によく使うよ。 で、ゲームパッドを使用したプログラムを開発するにあたり、参考になるHPはないの?
Windowsのメッセージディスパッチだろう。
>>615 このスレは環境依存可だけど、Win32スレの方がいいかもよ。
>>622 C/C++では、あまりディスパッチと言う表現は使わないね。
どちらかと言えば、スレッド、マルチスレッド、cellでのプロセスパイプ、等かな。
>>624 に追加、Windowsのメッセージディスパッチも有った。
626 :
623 :2008/07/13(日) 16:20:39
Windowsのメッセージディスパッチとは限らないか。 それはともあれゲームスレで聞いた方がよさそう。
ダブルディスパッチパターン
>>627 確信犯はだめよw
Modern C++ Designだよね。あれは使いどころが難しそうだな。
>>615 ちかごろの事情はあんまりわかんねえんだけど、
Windowsの話なら最近はDirectInputが破棄されてXInputを使うのが推奨されてる。
>>624 > スレッド、マルチスレッド、cellでのプロセスパイプ、
どう見てもディスパッチとは関係ないと思うが。
4byteのクラスをnew演算子で250000個確保したところ、 タクスマネージャで確認した範囲で、メモリを15580KBを消費しました なぜ16倍も消費しているのでしょうか? boost::poolで確保した場合は、計算どおり1MBくらい消費しました
>>632 > 4byteのクラスをnew演算子で250000個確保したところ、
このコード貼れる? そんなに長くないよね。
634 :
デフォルトの名無しさん :2008/07/13(日) 17:06:16
>>597 > 参照が出来た理由を聞いてたの?
> C++は何故参照なんて機能を用意したの?って聞いてれば
> おそらくは、俺含め何人か答えてたんじゃない?
お前、自分の間違いを認めるのがよっぽど嫌いみたいだな。
どんだけ屁理屈だよ。
管理領域
とアラインメント
637 :
デフォルトの名無しさん :2008/07/13(日) 17:09:08
>>601 >
>>600 > 仕事の話と初心者の質問を一緒にされてもね・・・w
> あなたが手取り足取り教えてあげてはどうですか?
なにお前はこのスレで頭悪いのを披露するのが仕事だったの(w
てっきり初心者とかの質問に答えるスレだと思ってたよ。俺は。
>>632 自分でnewの中身(つーかmallocだな)書くこと考えてみな。
何でか想像つくだろ。
boost::pool は要するに new CHoge[250000] なんじゃねーの?
639 :
デフォルトの名無しさん :2008/07/13(日) 17:10:48
>>632 64バイト荒いんで確保する仕様なんじゃね?
640 :
デフォルトの名無しさん :2008/07/13(日) 17:11:57
解決しました ありがとうございました
641 :
デフォルトの名無しさん :2008/07/13(日) 17:13:09
>分かりやすいかどうかじゃなくって、C++とか外国人が作ったわけで >外国人から見ればこの記述法のやりやすいってだけの話で 少なくとも、こんなこと言っている奴が人にものを教えちゃだめだろ。 外国人が考えたから仕方ないのです、って何時の時代の人だよ?
お前誰だよ
643 :
デフォルトの名無しさん :2008/07/13(日) 17:14:03
引数でポインタ渡しだとヌルポがくる可能性あるけど 参照渡しなら変なことしない限りヌルポにならないから便利。
644 :
デフォルトの名無しさん :2008/07/13(日) 17:14:06
>>633 class CA{
public:
long x;
CA(){x=0;}
CA(long a){x=a;;}
};
int const NUMS=500;
main(){
CA *x[NUMS][NUMS];
getchar(); //ここで消費メモリ2340k
cout << sizeof(CA); //"4"と表示される
for(long i=0;i<NUMS;++i){
for(long j=0;j<NUMS;++j){
x[i][j]=new CA(i);
}
}
getchar(); //ここで消費メモリ18160K
for(long i=0;i<NUMS;++i){
for(long j=0;j<NUMS;++j){
delete x[i][j];
}
}
getchar(); //ここで消費メモリ2580k
}
645 :
デフォルトの名無しさん :2008/07/13(日) 17:14:55
誰
646 :
デフォルトの名無しさん :2008/07/13(日) 17:17:47
>>635 ちなみに空き領域だけに管理情報を書く実装も
あるので管理領域というのは間違い
アロケート後の領域はアロケータの管理外になる
粘着キチガイまだ居るのか・・・
匿名掲示板でお前誰だよと訊く馬鹿
俺だよ俺
>>646 おまえはfree(p)するときにpの領域の指すサイズがわかるのかよ。エスパーか。
ていうか、「偉そうな書き方」「age」という、知ったかの典型な野郎だな。
デストラクタの中で例外発生させてはいけないのはなぜでしょうか? また、やむを得ず例外発生する関数を使ってしまった場合、 具体的にどのような対策を採れば良いのでしょうか?
>>646 じゃあアロケート後の状況を管理するための情報を保持する
メモリーのことは何というのか?
>>650 *(p-1)とか*(p-2)あたりに管理情報置いてるallocatorもある
>>646 とりあえず、その「例」を挙げてくれよ。
あ、特定サイズに限定してのpoolでの利用時、ってのはナシな。
それじゃサイズ情報が固定になっちゃうから。
>>643 自分もそう思って参照を使ってるけど、
最近ではポインタの方がいいかなと思い始めてる。
利用時に見た目で区別できた方が保守性が上がりそうだから。
ポインタとヌルポの扱いが悩ましくなるけど、皆どうしてる?
自分は、ヌルポは指定不可とドキュメントに書いてアサートしてる。
(privateメンバ関数はもちろん、publicメンバ関数でも)
NULLの場合にはFALSEを返したり例外を投げる方がよいという意見もあるだろうけど、
ドキュメントとアサートで十分な気がしている。
>>644 &x[0][0] と &x[0][1] の差を出してみ。
それでなんとなくわかるべ
>>653 だから『*(p-1)とか*(p-2)あたりに管理情報』は管理領域じゃないのか?
>>653 バカかお前は。
それは「管理領域として消費しているメモリ」そのものだろ。
>>651 例外を投げない宣言をするといい
~Hoge() throw() { fuga(); }
それでも投げられてしまったら
void unexpected() が呼ばれるが
std::set_unexpected(unexpected_hander);
とかで自前のものに変更可能
>>653 ワロタw
管理領域って何だと思ってたんだよw
>>655 真実に気づき始めてるみたいだから後押しするが、参照で渡したい
ものはパラメータへの積み込みにコストがかかり(つまりでかい)
中で書き換えが発生しない場合に限った方が良い。
NULLポインタ禁止はドキュメントで十分だが、その辺は
好きにしていいと思う。
>>651 ちなみにコンストラクタから例外を投げていいかどうかは賛否両論あるね。
賛成派が多い感じがするけど。
>>655 > 利用時に見た目で区別できた方が保守性が上がりそうだから。
こんなこと書いている段階で駄目だろ。
666 :
655 :2008/07/13(日) 17:38:14
>>663 参照の方がコストがかかるって本当?
内部的にはポインタと同じくアドレスを渡してると思ってたけど違うの?
>>665 何言ってるんだ。
その(見て分かる)ために書き換え可能性のある場合はポインタで渡すんだよ。
668 :
655 :2008/07/13(日) 17:40:46
>>666 >参照の方がコストがかかるって本当?
値渡しに比べて、だね。
コストはポイントと同じ。
>>663 >>>>> C++標準委員会
というわけですね、わかります。
CにしろC++にしろ前提条件が「プログラマは、すごい人だからミスなんてしないよね!」っていう仕様に なってるんだよ。クソッタレな馬鹿は見た目で区別したできた方が保守性が上がりそうとか言い出す。 だから呼び出しコストに鈍感なクズプログラムを量産して迷惑掛ける。
672 :
デフォルトの名無しさん :2008/07/13(日) 17:47:09
ドカタは黙ってろよ
673 :
655 :2008/07/13(日) 17:47:59
>>667 そうそう。思うに、
「NULLチェックしなくて済むから参照にする」
→「その関数作った自分は書き換えられること知ってるから問題ない」
→「他の奴はドキュメントよく読め」
ってなりそう。それは自己中だよね。
>>669 だよね。
まー、不器用な奴はC#でもJavaでもやってろってことだなw
>>671 2行目と3行目のつながりが分からない。
今はポインタ渡しと参照渡しの話をしていて、コストは同じ。
今日も大荒れだな。
>>673 だからさー「NULLチェックしなくて済むから参照にする」
ってのをやめようとしてるのに何罵倒してるんだ?
NULLが渡された時どういう挙動にするかはコードの
用途次第だろ?
パフォーマンス優先でNULLチェックもしたくない場合は
動作未定義とドキュメントに書いておいて、使う人間に
NULL呼び出ししないことを保証してもらうのがベストだし。
>>673 見て分からないメンバ関数は書き換え禁止?
a.countUp();は
countUp(&a);にすべき?
そ、それは……
参照の騒動でも思ったけど、値が勝手に書きかえられちゃうような 関数呼び出しをするのは調べない方が悪い、みたいな態度で相手を 馬鹿にしている書き込みがあったけど、そういう奴こそ、基礎に戻 ってモジュール結合度とか、カプセル化の意味とか考え直して欲し いものだと思った。
>>667 書き換える可能性だけで言うなら、ポインタだろうと参照だろうと
仮引数にconstをつけて書き換えないことを明示する
(=constが無ければ関数内で書き換える可能性がある)のが普通だと思うんだけど。
682 :
673 :2008/07/13(日) 18:04:32
673は自分を罵倒してるんですが。。。自己中なのでやめようと思うということです。 書き方が悪かったかな。 4行目以降は全く同意です。
>>681 >仮引数にconstをつけて書き換えないことを明示する
いやいやいや、ここでの明示の価値は、宣言部分じゃなくて
使用してるところで明確にすることにあるんですよ。
宣言部分で万事OKなら、
>>678 >>679 とはならないよよよ
ドキュメントなんて一切見なくてもちゃんと組めるのが理想だろ。 そういう設計にすべきなのに、事あるごとにドキュメントに頼ろうとする奴はアセンブリにでも埋まってろ。
>>680 説明も読まずに関数やクラスを使っちゃうような人に基礎の話をされてもねw
値を書き換えられるのが嫌な人はHaskellとかErlangあたりを使えばいいと思うよ
687 :
673 :2008/07/13(日) 18:13:43
>>678 それはこの話とは別と思ってます。
>>681 それは同意ですが、
書き換え不可の場合はconst参照が一般的なので、
書き換え可能な場合はポインタにすると書き換え不可と区別がつけられるという話をしています。
688 :
デフォルトの名無しさん :2008/07/13(日) 18:16:26
「それとこれとは別」って何の意味も無い言葉だな。 関係があると思うからそういう例を出してるのに、単に「別」と言われても。 別だと思うならどこが違うのか理由を言えと。
まあ仕事でやればわかるけど自分以外は何やるかわからないキチガイと考えて 防衛的なプログラムを書くもの。
690 :
673 :2008/07/13(日) 18:18:40
>>687 >>書き換え可能な場合はポインタにすると書き換え不可と区別がつけられるという話をしています。
→「呼び出し方を見るだけで」ということです。
>>688 >「それとこれとは別」って何の意味も無い言葉だな。
な、何も汲み取れないのか…?
>>690 それで、「呼び出し方を見るだけで」区別が付けられない
>>678 のような例は?
別の話なの?
693 :
673 :2008/07/13(日) 18:23:33
>>688 「書き換わることが見た目で分かるかどうか」という観点では関係ありますが、
今している「引数を参照VSポインタ」の議論とはメリット/デメリットが変わってくるので別の話と思います。
694 :
デフォルトの名無しさん :2008/07/13(日) 18:23:56
>>691 自分が勝手に前提としているものが、人にも通用するとは思わない方がいいよ。
自分とは違う視点もあることを知った方がいいよ。
>>690 それはあまりにもひどいローカルルールじゃないか。
他人が見たときに「一貫性の無い野郎だな」でスルーされるかもよ?
利用側で書き換え禁止を明示したいだけなら
int x = 0;
somefunc(static_cast<int const &>(x));
と書くとか、コメント書くほうが健全だと思うんだけど。
>>689 × 自分以外は
○ 自分も含めて
# 一週間以上前の自分は他人だと定義する方法もあるが。
>>694 普段よほど自分の言うことが他人に理解されない生活送ってるんだねかわいそうにw
>>693 そのように知恵のある人間なら解釈すべきだと思う。
ちゃんとニュアンス伝わってる人間も居るので心配しなくていい。
ここは明らかに汲み取れない方が鈍感。
698 :
デフォルトの名無しさん :2008/07/13(日) 18:27:43
一つの話しかできないのかよシングルタスク野郎め
別に自分ひとりで開発するならconstなんていらないけど 共同開発をするなら、視覚的に分かりやすく、ソースを見ただけでわかってもらえるように 関数にもconstつけるんだろ
>>695 >それはあまりにもひどいローカルルールじゃないか。
んなこたーない
>他人が見たときに「一貫性の無い野郎だな」でスルーされるかもよ?
書き換えるときのみポインタで渡すことで一貫させようという話だろ
701 :
デフォルトの名無しさん :2008/07/13(日) 18:30:43
話が通じないな。 「ニュアンス」なんて自分勝手で曖昧なものを、いつでも汲み取ってもらえるなどと思うなってことだ。 そもそものところ、一度に一つの議論しかできないのかと。
相手を黙らせたいなら誰もが納得する説明でピシャっと決めろよ
>>699 >別に自分ひとりで開発するならconstなんていらない
そんなばかな
>ソースを見ただけでわかってもらえるように関数にもconstつけるんだろ
それは当たり前
>>701 ちがうね
自分が汲み取ってもらうことを期待してるんじゃなくて、誰かの言うことを
汲み取れるようになれって言ってんの。
>そもそものところ、一度に一つの議論しかできないのかと。
メンバ関数呼び出しの話か? 君こそ他人が複数の話題に
ついてこれることを期待しちゃってるんじゃないの?
文章しかないコミュニケーションで汲み取れとかアホらしいこと言わずに 文章だけできちんと伝えられるようにしろ
class Tがあって、宣言を func1(const T &arg) func2(T *arg) と書いといたら、呼び出し側は必然的に func1(arg) func2(&arg) としなきゃいけなくなるから、「そのルールを知ってれば」ソース上で書き換え禁止かどうか判断できるという話ではないの? そう解釈しているんだが。 私もそうしてる。 Cから入ったせいか、見た目が値渡しなのに中身が変わるのは気持ち悪いんだよね。 ルールを知らない人向けに(まぁ、自分以外は知らないだろうけど)関数ヘッダにも別途書き換えする場合はその旨記述しておくが。
>>560 嫌われる理由は、暗黙の型変換に起因するトラブルやわかりにくさのため。
std::string が operator char* ではなく、c_str() を用意しているのもその
せい。暗黙の型変換による影響範囲を特定できて、可読性の向上にも寄与
するなら使ってもいいと思う。そういうケースを思い付かないなら使わない。
>>693 以下の最後のケースだけを重視して、あとはどうでも良いと?
それは一貫性が無いんじゃない?
//(1)
char buf[100];
f1(buf); // bufに変化があるか、見た目で分からない
//(2)
A insA;
int n = insA.countUp(); // insAに変化があるか、見た目で分からない
//(3)
int b = 0;
f2(b); // bに変化があるか、見た目で分からない
//(4)
int c = 0;
f3(&c); // cに変化があるかもしれない、見た目で分かる
×複数の話題についてこれることを期待 ○勝手に振った話題についてきてくれると期待 で、ついてきてくれなかったら切れるわけだ。無視されたーってw
711 :
デフォルトの名無しさん :2008/07/13(日) 18:42:24
「値が変更されることは、見てわかるようにすべき」という主張だろう。
だったら
>>678 の質問もおかしくないんじゃないの?
この書き方だと、値が変わるか変わらないかは関数の中身を見ないとわからない。
いちいち見に行くのが嫌だから、呼び出しの時点でわかるようにしようって話なんだろ。
逆にこの書き方はOKだとするなら、何故参照渡しがいけないの?
ポインタを渡していないけれど値が書き換わる、という点で同じじゃないか。
何かよく分からないんだけど、 「const参照とは違う渡し方をしてるから、これは書き換えられる可能性があるってことね」ってことなの? 読み手がその勝手規約を知っているか勘の良い人だっていうことを前提としてるように見えるんだけど、 もっとズバッと分かりやすいやり方は無いの?
713 :
673 :2008/07/13(日) 18:44:56
>>709 全部分からないより//(4)に関して分かってる方がより建設的じゃね?
それから//(3)に関して変化しないことを見た目でわかるようにしよう
というルールだし。
//(1)//(2)はお前の嫌いな別の話。これらがあるとしても//(3)//(4)に
関して十分有効なルール。
>>715 (1)も別の話ですか、
十分有効なルールとか本気で言ってるの?w
>>711 >逆にこの書き方はOKだとするなら、何故参照渡しがいけないの?
他に、値渡しと区別がつかないから、というのもある。
区別がつかないなら、値渡しと見た目が同じ参照渡しでは、
呼び出し側の変更が無いものというルールにすることは、
そんなに反感招くほど悪いものではないだろ。
>>716 残念ながら別の話だし、有効だろうね。
なんか知ってるか知らないかという話の気がしてきた。
719 :
デフォルトの名無しさん :2008/07/13(日) 18:53:23
ほーらニュアンスなんかに頼ってるから議論がぐちゃぐちゃになっていく。 「参照渡しをすべきではない」と思う理由を明確にしろ。後付けのわがままは許さない。
「参照渡しをすべきではない」→「値を変更する参照渡しをすべきではない」
だな。
>>717 は妥当だとは思わないか?
まあ仕事でやればわかるけど自分以外は何やるかわからないキチガイと考えて 防衛的なプログラムを書くもの。
反対派の人はまず
>>713 のGoogleの説明を読んでからだね。
(
>>714 の日本語版では全部訳されてない。)
723 :
デフォルトの名無しさん :2008/07/13(日) 19:02:27
妥当だと思わない人間がいるから議論になってるんじゃねーの。 こんなの個人的な嗜好の問題なのに、反対する人間をも納得させようとして、 変に話を大きくしてるから突っ込まれるんだよ。
const char * hoge; char const * fuga; の違いを教えてください
ポインタ型の変数とか使ったことが無いのだろうか・・・ 普通に値渡しで、指す先が変更されることもあるんだけど、 ポインタ値自体が分からなければOKってことなのかな?
Googleを業界基準にしようなんておこがましいにも程があるとはおもわんかね C++の規格に沿って話せよ
>>721 どっち派なんだ? 仮に値変更可能な参照渡し容認派なら、
>防衛的なプログラムを書くもの。
それは「値を変更する参照渡しをすべきではない」という主張と
別に相容れないものではないじゃないか。
むしろconstじゃない参照パラメータを書かないのだからより
安全だろう…あ、つまり反対派なんだw
729 :
デフォルトの名無しさん :2008/07/13(日) 19:06:41
どっち派とか下らないレッテル貼らないと話もできないわけ?
>>704 未来の自分は他人ってスレの中で定義されてるんだから
可読性を考慮しないで、1日でくみ上げちまえば「自分」だけになるんじゃね
>>723 >妥当だと思わない人間がいるから議論になってるんじゃねーの。
では
>>717 のどこがおかしいのか言ってくれたまえ。
個人的な嗜好は不可ね。それ言ったら何でもありになっちゃうから。
その「嗜好」になった理由があるだろ?
const char * hoge; char * const fuga; の違いを教えてください
>>733 hoge = NULL; //コンパイル可能
*hoge = '\0'; //コンパイル不可
fuga = NULL'; //コンパイル不可
*fuga = '\0'; //コンパイル可能
>>725 さほど奇妙な話ではないかと。
ポインタ値自体は値渡しだから変更はない。
ポインタの先は「ポインタ渡し」だから変更される。
>>707 にあるように、Cでは値が変わる場合は普通ポインタ渡しになる。
値渡しでは通常値は変わらない。
C++で参照渡しをすると、値渡しのように見えるが値が変わってしまうから分かりにくい。
だから参照渡しの場合は値を変えないようにしよう(値を変える場合はポインタ渡しにしよう)っていうルール。
Googleの説明もそんな感じ。
どうも反対派でグッとくる意見がないね。
>>736 結局は「見える」ってところが重要なんだよな?
char* str = malloc(100);
strcpy(str, "aaa");
は&strになってないけど、どうなの?
というような質問には別の話とか言って答えないだろ?
struct iterator{
int* p;
};
みたいなのも値渡しで、結果的にpの先が書き換わったりすることもあるし。
std::のアルゴリズムとか。
それらについてはどうなの?
>>709 の(1)と
>>737 ポインタ渡しだから変化があるかどうかは分からない。
それはこのルールの対象外。
このルールは「参照渡しの場合はconstであること」。
ポインタの場合は、「変わる可能性がある」ことに気づきやすい。
参照の場合は値渡しと同じに見えるから気づきにくい。
これで分かりますか?
他のケースがあるから、そのルール(制限)には意味が無いって言ってるんですが、 分かります?
参照なんて不要
>>739 ドライバーがアクセル全開にするかもしれないから
制限速度の法規には意味がありませんか?
>>741 「その」の意味分かります?
誰も「ルールは意味無い」なんて言っていませんが。
>>742 「わかります?」じゃなくて、わかって欲しい内容そのものを書いたほうがいいよ。
本当は何も頭の中にありはしないのに、知見を隠し持ってるフリしてるようにしか見えないから。
発想を逆転させ、関数側で書き換えないことを保障する代わりに、 こんな感じで呼び出し側でconstで渡すというのはどうだろう。 template<class T> const T& const_ref(T& v) { return v; } //hoge(fuga& r); hoge(const_ref(arg)); //エラー
>>739 意味はあります。
他のケースよりも問題になりやすいからできたルールです。
全て対応する必要はないし、対応できないケースはあるでしょう。
>>746 毎回付けるにはその名前は長い気がするので、単項のoperator+でどうだろう
hoge(+arg);
>>707 > Cから入ったせいか、見た目が値渡しなのに中身が変わるのは気持ち悪いんだよね。
お前はC++に向いていない。
C++の流儀に従えないのなら一生Cやってろ。
>>747 それで、対応出来るケースは非常に小さい範囲というのがこちらの主張で、
そのルールによってstd::swapなどを否定するほどのメリットが有るとは、
思えません。
>>746 それはもう考えたんだけど、
値渡しを含む全ての引数にやらないとポインタ渡し派規約と同じ保証が出来ないよ。
>見た目が値渡しなのに中身が変わるのは気持ち悪い これだと、std::sortも否定されますね。 まぁ、std::vector<T>::iteratorなどがポインタだった時期もありましたが。
昔Cは関数呼び出しのとき、値渡しが原則で、参照の時は明示的にやるので 呼び出し側から、呼び出した結果引数の内容が気づかないうちに変更されている 危険がなくて安心、とかいう説明をきいた記憶があるのですが、C++は呼び出し 側から値渡しか参照渡しかわからない書き方ができるので、これは退化じゃない かと思うのですが、違うんでしょうか?
機能として存在しているのに、使わないのが正しいとか言い出すからおかしくなるんだよ。 C++とはそういうものと考えて使えば良いだけの話。 いい加減荒らすな。
別スレでやればいいのに
758 :
747 :2008/07/13(日) 20:08:21
>>751 了解です。私も元々このルールを使っていなかったので、押し付けるつもりはありません。
(そう読めたらごめんなさい)。
誤解があるかもと思って説明しましたが、そうではなかったようで、
あとは各人の経験や嗜好に基づく部分と思いますのでここらで失礼します。
そろそろ goto とか longjmp の出番か?
>>755 char* str = malloc(100);
strcpy(str); //全然明示的でない件について
アプリケーションハンガリアンが解決してくれる
まあ書き換える可能性がある関数は 大抵WriteParameter(param);とか名前で分かるし、 IDEの機能で引数の型が表示されたりするしなぁ。 あんまり気にしたことが無かったというのが正直なところ。 ただ、ポインタ渡し派の規約には たとえ紙に印刷されていても規約を知っていれば読めるとか 引数ごとに細かく明示できるという利点を感じた。
>>760 結局、向こう側に「何をされるのか」は、向こう側のことがわからないと
どうにもならないからなぁ。
>>760 その関数はポインタを受け取るから変更の可能性アリ。
なんか&の表記があることと混同してる奴がいないか?
>>760 > char* str = malloc(100);
> strcpy(str); //全然明示的でない件について
このレベルで回答してたのか。
馬鹿すぎる・・・
>>765 つまり、ポインタを渡す場合には、変更の可能性があるかもしれないことを
受け入れるわけだよね、それって。
>>766 >>755 では「関数呼び出しのとき」値渡しが原則で参照の時は「明示的に」やるので
とあるけど、strcpy(str)のどの辺が明示的か説明して貰えるかな?
結論:外国人が決めたルールに従え
吹いたww
>>766 そのレベルがどのレベルなのかはっきりしないけど、
元の話題がそもそもそういう話だからね。
「どっちみち、呼び出し先で引数に何をされるか予想できない関数呼び出しに満ちているんだよ」
ってことだな。
何番目の引数が書き換わるかすぐにわかるような新しい関数の命名法を考えるといいんじゃね
>>752 全部付ければ良い。
変えて良いときだけref付けたりポインタ渡しを強制するのも、
変えちゃダメな時にconst_ref付けるのも、本質的には同じ対処。
どちらを優先するかな違いだけ。
そもそもswap( int &a, int &b)なんて宣言してswap( a, b )なんて使い方している奴いるの?
C#みたいに呼び出し側でrefをつけるようにすりゃいいんじゃね? なんかC++の機能制限に繋がるのか?
>>773 >「どっちみち、呼び出し先で引数に何をされるか予想できない関数呼び出しに満ちているんだよ」
だから参照渡しは書き換えないようにしようって発想なんだろ。
何が気に入らないんだ?
つ STL
>>776 どういう状況でどのスタンスの人間に訊いてるのか、よくわからないが・・・。
とりあえずSTLのswap関数はそうなってるよな。
ていうか、swapなんだから、ああ、値が入れ替わるんだな、ってのは容易に想像できるし。
(むしろ、swap関数なのに引数が変化してなかったら、そっちのほうが驚きでは)
誰かεπιστημη呼んで来いよ
>>776 いかにも覚えたての人間が嬉しくてやる例だよね。有用でないと
までは言わないが。
演算子オーバーロードのために導入された参照が、たまたま
Cの時にマクロで作られていたswapとかに流用されただけだし。
>>780 > ていうか、swapなんだから、ああ、値が入れ替わるんだな、ってのは容易に想像できるし。
俺なんか名前から容易に想像できる関数たちに散々裏切られてきたぜ。
同僚が作ったのとかMSが作ったのとか。
だから俺も裏切ってやることにした。
>>778 なにがどう「だから」なのかわからんのだけど。
ポインタはいいの? 書き換えられない保証付きの手段が無くても。
異常にスレ伸びてると思ったら
くだらん宗教論争やってんなーと思って静観してたけど
>>783 > だから俺も裏切ってやることにした。
お前の最後の一行になんか和んでしまったw
流れに便乗して質問 void copy1( vector<int> &dst, const vector<int> &src ); void copy2( vector<int> *dst, const vector<int> &src ); vector<int> foo; vector<int> bar; copy1( foo, bar ); copy2( &foo, bar ); こういう場合ってどっちの方がいいのかな?たまに悩むんだけど strcpyみたいなのにあわせればcopy1だけど、 copy2の方がわかりやすいのかなとも思うし。
>>784 書き換えたいからポインタで渡すんだろ、って話では。
f(T&)くらいも気に入らないと言ってる人は C++0xの右辺値参照とか入ってきたら発狂しそうだよな
>>786 strcpyにあわせるとcopy2だろ。
呼び出し先で書き換えて欲しくない文字列を渡すとき、については、 「参照を書き換えるな派」は黙って受け入れるということでいいのかな。 char* p = new char[sz]; // pの指すchar配列の範囲に色々詰め込む hoge(p); // 文字列書き換えられたくないなぁ・・・でもいいや! // ポインタ渡しならボクはその可能性にも耐えられる!何故かポインタだけは!
>>790 参照書き換え不可派じゃないが、
const char* p = new char[sz];
か
hoge((const char*)p);
でOK
そうやってるわけね。いつも。
いや、普通に関数のヘッダみて確認しますよw
俺もクラスの定義見て確認するからメンバは全部publicでいいよ。
IDEやエディタが非const参照・ポインタの引数に色付けてくれればいいんじゃね
>>794 そう。746,749と同じ考え。
書き換えて欲しくないとき、そう明示する手段があるのだから使えば良い。
書き換え無い保証が欲しいが、引数型の確認もしたくないとか言うのなら、
constで渡すくらいの手間は我慢するしかないと思うのよ。
vector<int> foo; vector<int> bar; copy1(foo, static_cast<const vector<int>&>(bar)); ちなみにjava List<Integer> foo; copy1(foo, Collections.unmodifiableList(bar)); どちらも、実は使ったことがある。
こういう個人的な好き嫌いや感情で正しいとか間違っているとか宗教戦争がすぐ発生しちゃうから C++は駄目言語なんだよ。 ずうたいばかり大きくなった恐竜みたいなもの。 早く滅びてC#やJavaに道を譲った方がいい。
C++が駄目なんじゃない!宗教戦争を起こす人間が駄目なんだ!
>>801 C#やJavaでの宗教戦争に参加したことが無いようで。
いや、参加しない方がいいんだけどね・・・w
ちなみにインデントの宗教戦争は言語をも越えて勃発するw
>>801 言語の良し悪しとは関係ないんだから別に良いんじゃない?
Javaは臭い金の臭いしかしないから好きになれん。
C♯はMonoプロジェクトの頑張りでもっともっと普及すると思う。
大体創始者の名前の読みにくさとかハゲ頭みたときから怪しいと思ってた。
>>804 TAB派かスペース派か
俺は断然スペース派
おれはIDEお任せ派
俺は1行79文字インデント無し派
>>806 ワールドワイドで考えると、名前の読みにくさと、持ってる宗教の怪しさでは
Rubyの人が一番だろうけどね。
Wikipediaだとビャーネ・ストロヴストルップとなっているけど、これで定着してるの?
Eclipseのデフォルトのインデントの無能っぷりは異常w
>>811 Wikipediaにしては珍しく記事名で議論が出てないな。
火つけたらきっとよく燃えるぞw
>>811 皆結構好き勝手に読んでる、C++スレでは「びよよん」って呼ばれてた
>>807 >俺は断然スペース派
このスレじゃなかったら、銃を向け合うところだったな
なんてなw 俺はT(ry
俺はもっぱら4tab派だけど、同じファイル内で統一されてるなら、タブだろうがスペースだろうが好きにすればいいと思うよ 自分のコードさえ汚されなきゃキレない・・・と、思う あー、やっぱ見にくいのを読まされるのはヤダな
javaの標準ライブラリは一つのファイル内でも統一されていないから困る 4TABと8TABで切り替えると、どこかが綺麗になってどこかが崩れるw
もう最近は、インデントは、テキストに保存されてるのとは別に、IDEが ユーザー定義のルールで整形しなおして表示しちゃえばいいと思う。 どうせC系は改行やスペースにほぼ意味無いんだし
Cの場合、マクロがやっかいになるな それだと
TABかスペースかはおいといて、世界で初めてインデントした人って誰なんだろう? 凄い地味だけどこれは素晴らしい発見だと思う。
>>823 俺も。
つーか普通にやってりゃかなりの確率で発見するような気がせんでもない。
でも、BASICにはその概念ないよな
QuickBASIC以降はあったような
>>825 確かに何かしらの工夫はするだろうね。
まだソースを見やすくする工夫が存在していない状態と仮定して、
俺ならどうするだろう。
多分コメントで
// A処理開始
print ('A');
//A_B処理開始
print ('A_B');
//A_B処理終了
// A処理終了
ぐらいしか思いつかんだろうな。
あとはエディタで色分けぐらい?
少なくとも、一行の文字数に制限があった時代にインデントはなかっただろう
FORTRAN FORTH PYTHON
何時代かはわからんが
>>831 が40以上なのはなんとなく分かる。
若くても文字列処理用とか勉強用ならやってるやついるんじゃないか? 俺はよく分からんが・・・ FORTRANは昔読んでたC言語の本に併記されてたから、ある程度読める
FORTRANは始まりの桁数も決まってたしなあ。 COBOLはある程度自由だったが。 BASICは入力するたびに勝手に整形されてたしな
835 :
デフォルトの名無しさん :2008/07/14(月) 01:04:38
C#も勝手に整形しやがるよ 何かMSの言いなりみたいで癪だ
VSの設定で変えられるだろ
そろそろ穿孔カードの話を始める団塊の世代が現れるな
整形してくれるならそれに流れるように身を任せてるよ
マグロですね、わかります。
むしろブレースの位置とかも指定できなかったっけ? indentコマンド使わなくてもよくなる時代が来るかね
842 :
758 :2008/07/14(月) 01:27:37
758
>>693 の(1)(2)と736の前半がなぜ別問題なのか説明できるようになったので
戻ってきてしまいました。頑張って考えてきました。聞いてください。
なぜ別問題か?それはこの問題の本質が、
「変化があるか見た目で分からない」ではなく、
「参照渡しと値渡しで呼び出し方が同じであるため、
参照渡しと気づかず、知らぬ間に書き換わっている可能性がある」ということです。
参照をconst限定にするのは、この問題を回避するためです。
(気づかなくても、constだから書き換わらない)
ポインタ渡し(1)やメンバ関数(2)については、呼び出し方を見て、
ポインタ渡し/メンバ関数呼び出しであることがわかるため、
この問題がない、あるいは少ないです。
>>693 の例で言うと、(1)(2)(4)については「変化があるか見た目で分からないが、変化がある可能性を認知できる」が、
(3)については「値渡しと思い込んで、変化があると思いもしない可能性がある」ということになると思います。
この違いがあるため、別問題と考えます。
(全部参照渡しを疑うべきっていうのはなしとして話してます)
843 :
758 :2008/07/14(月) 01:28:35
>>790 さんは、このルール支持派が参照はconstで、ポインタは書き換え可能なことを受け入れることに違和感を感じられていますが、
上で述べたように、「変化があるか見た目で分からないが、変化がある可能性を認知できる」というのは望ましい状態であり、
その状態は受け入れるスタンスなわけです。
以下はちょっと余談気味ですが、
真の問題を回避するには、「参照禁止」というルールでもいいのですが、
C++ではコピーコンストラクタや代入演算子などでconst参照が使われますし、
値渡しの変わりにconst参照渡しが使われるのは一般的なので、
「参照はconstにする」というルールになっています。
また、なんらかの形で呼び出し側で値渡しと参照渡しが区別できればこのルールは当然不要と思います。
次にswapの存在などにより、参照をconstで統一できないという指摘ですが、
これはもちろん別問題ではなく、「統一感がない」というデメリットになります。
そのため意味がない、という意見も分かります。
実際の現場では、使用するライブラリや既存コードがこのルールに則っているかや、
メンバのスキルやバックグラウンド、嗜好などにより、メリットとデメリットを比較して
導入を決定することになると思います。
最後に、議論を通じて自分の考えがより深まりました。ありがとうございました。
では今度こそ本当にさらばだ。でゅわ!!
さっき758をC++標準化委員会のボードメンバーに推薦してきたので、以後その話は そっちでやって下さい。
845 :
デフォルトの名無しさん :2008/07/14(月) 01:37:41
>>842 要するに君が望むのは、
「C言語における値渡しの書き方ならば絶対に値が書き換わらない状況」なんだろ。
それについては何も文句は無いし、実際に便利だと思う。
でも、それ以外の書き方についてもごちゃごちゃ言い始めたから面倒なことになったんだ。
下手に一般化しようとして話を広げたからいけないんだ。反省しなさい。
あまりに議論が白熱してて読むのもめどいんだが、値型、参照型の2種類存在してることが そもそも気に食わなかったりする?
参照渡しなんか考えた奴誰だよ、泣いて謝れよ
びよよんだ文句あるかね
constな参照渡しって結局値渡しと何が違うんですか? (意味の違いは分かってますよ)
気持ち
オブジェクトがでかいときのオーバヘッドが違うだろ
それならポインタで充分じゃないですか?
参照は要らんよ C++は何でも盛り込み過ぎて破綻してる
ポインタは悪しき物だとして徹底的に排除して Javaとかで参照とかが出てきたんじゃないの? で、それをC++でも使えて何か不満なのかな?
>>854 順番がおかしい
それにC++の参照とJavaの参照は別物
解答のひとつがC#の f(ref a, out b) なんだろね。
マルチスレッドプログラムでコンソールにエラー出力をする場合の素朴な疑問です。 Cでいうところの下記のような動作を期待して、 fprintf(stderr, "%d%d\n", 1, 2); C++で下記のようにコーディングしてみました。 std::cerr << 1 << 2 << "\n"; しかしこれでは複数のスレッドから書き込みを行った場合、 タイミングによって1と2が分断されて出力されてしまいます。 これを下記の条件内で解決する方法はあるのでしょうか? ・C++標準の範疇で(環境依存のスレッド同期APIなどを使わずに) ・iostreamの範疇で(std::fprintfなどを使わずに) ・例外で失敗せずに(std::stringstream::str()を使わずに) それともこういう場合は素直にstd::fprintfなどを使うのが正しい選択なのでしょうか?
そもそもC++にスレッドなんて概念ないから、 連結してから書き出しても何らかの理由で割り込まれたりするんじゃねえの。 ある程度、環境依存になるのはしかたないよ。
そもそも環境に依存せずにマルチスレッドを使うことは出来ないはず
860 :
857 :2008/07/14(月) 03:24:13
ありがとうございます。 確かにマルチスレッドな時点でC++標準ではないですね・・・。 もう一度考え直してみます。
861 :
デフォルトの名無しさん :2008/07/14(月) 03:28:53
バッファにため込んで、一度に(ファイルなどへ)書き込めば平気なはず。 モニタだと別のやつが先に来るかもしれないが
862 :
デフォルトの名無しさん :2008/07/14(月) 03:42:46
ファイルでも別のが先に来る可能性はあるな。 同時にアクセスしているのだから。 書き込みが終わるまで待つ必要ある。 ロックする。
じゃあ同時にロックされたらどうなる? とか考え始めると泥沼にはまってデッドロックの理論も勉強するはめになる。
マルチスレッド嫌い。
そこで「マルチスレッドでコンパイルする」な人の出番ですよ。
867 :
デフォルトの名無しさん :2008/07/14(月) 05:54:48
Lock-freeとWait-freeアルゴリズム - Wikipedia のほうがよくないか? 画面表示するデータを、キューへいれていき処理する方法。 これだと、ロック待ちが無い。
求められるパフォーマンスによってはそうだろうね。 その手のIO待ちを避ける手法は プログラムの複雑さとトレードオフになるので。
MFCでフォーム物作るのとC#で同じもの作るのはどっちが動作速度速いんですか?
サウンドのラインイン端子からデータ取る関数ってありますか?
>>869 同等に慣れていて、0から作るなら。
C#>>>>>MFC
↑ミス、作成速度と間違えた。動作速度なら MFC>>C#
MFC慣れたら簡単になってきたんだけど、C#のほうがそんなにいいのか また勉強するのは気力的に辛すぎるw
文法は似てるんだから、気が向いたらいつでも使えるよ。
MFCの方が速度速いんだ?なんとなくC#だと思ってたわ
C#はGDI+を使っている事もあり全体的に動作がもっさり
MFCは大きすぎ重すぎでやっぱりSDK生で書かないとといってた頃が懐かしい
VistaだとGDIがエミュになってのろまになったんだろ? 今後のC/C++のGUIって何で書けばいいんだ?
>>879 コマーシャル見て、「あ、これ買わなきゃ!」とかいうタイプですね、わかります。
そうかC#はCで作ったのか
WaveIn難しすぎませんか? 全然日本語の情報ページがないんですが
じゃどのくらい簡単ならいいのか書いてよ
日本語がへたですいません 日本語でWaveIn詳しく解説してるページないですか?
>543
そういえばそのコピペ4年前からあるな
>>843 デフォ型を全部const型にしておいて、>746,749の変形で
単項+で非constな参照を返すようにすればいい。
889 :
デフォルトの名無しさん :2008/07/14(月) 15:15:00
Cのあるプログラムで作った内部データを、C++の別プログラムに渡して使用することって可能でしょうか。 CからC++の関数を呼ぶこと自体はextern "C"を使えばできるっぽいですが、データの受け渡しをどうやるのか…。 例えばファイルを吐き出させてC++の方で改めてそれを読む、というのは考えられますが、できれば変数のまま やりとりをしたいと思っています。常識的な方法があるのだろうとは思いますが、勉強不足でわからないので、 よろしければ教えてもらえないでしょうか。
>>889 普通にどちらからもアクセスできる構造体なり配列を使えばいいと思うよ。
勿論、単純な整数型などの変数でも構わないし。
>>889 別のプログラムだから、ファイル経由したくないならプロセス間通信だね。
プログラムは同時に立ち上がってるんでしょ?
同時に動いていないならファイルに書き出すなりプロセス以外の状態での
データ保持を考えないといけなくなる。
関数を呼ぶってあるけどどっちなんだろね。
893 :
889 :2008/07/14(月) 15:57:33
894 :
889 :2008/07/14(月) 15:59:12
書き忘れ。 ググると、windowsAPIを用いた方法が山のようにでてきますが、今の環境はLinuxです。 できれば最初はOS依存性のない原理的な方法が知りたいと思っています。
895 :
889 :2008/07/14(月) 16:02:45
度々すみません。 TheUnixSuperText下巻の第9部がそれっぽい話題でした。 読んでみますが、他によりよい本があったら教えて頂けると幸いですorz
>>893 >Cの方のプログラムは既存のブラックボックス
この時点でどうにもならないのでは? C++の方から無理やり
プロセス内メモリを覗くことは不可能じゃないけど、目的とする
データがどこにあるかとか知らないとダメだし。
897 :
デフォルトの名無しさん :2008/07/14(月) 16:24:27
ブラックボックスのプログラムがどういったインターフェース用意しているかによるだろ たとえばDLLならそれ専用のアクセス方法があるように
>どういったインターフェース用意しているか それがわかるんならこんな質問してくるかね?
899 :
デフォルトの名無しさん :2008/07/14(月) 16:40:19
ブラックボックスのプログラムの仕様がわかないままで答えられない
何もかもすべて明らかにならないと話もしたくないなら、 書き込まなきゃいいのに
902 :
デフォルトの名無しさん :2008/07/14(月) 16:47:42
float型の数値データが入ったファイルがあり、 そのファイルからデータを読み出す関数 (下記のReadData())があります。 long a0, lbytes, len; void *buf ; lbytes=4 * 1024; buf = (void *)malloc(lbytes); len = ReadData(a0, buf); ファイルに格納されている値はfloat型だと 分かっているのですが、voidポインタで しかもバイト数でメモリを確保して読み出す 使用になっているため、bufで示される領域の データを、どうすれば1024個のfloat型の数値 に戻せばよいのか分かりません。 mallocでいろいろググッたのですが、確保される 領域に読み出されるのが、ひとかたまりの文字列 だったり、mallocの段階できちんとキャストされ ていたりで、上記のような用例がありません。 上記のように、float型の複数個の数値をバイト数 で指定したメモリ範囲にひとかたまりで読み込んだ ときに、これを元のfloat型の複数個の数値に直す (例えばfloat val[1023]; に代入するとか)は どうすればよろしいのでしょうか? なんか手がかりを頂けるとうれしいです。 なにとぞよろしこ。
>>902 float *float_buf;
float_buf=(float*)buf;
904 :
902 :2008/07/14(月) 17:04:02
読めたああああ! ありがとう!
905 :
889 :2008/07/14(月) 17:05:20
>>897 おそらくまともなインターフェースは用意されていません。
C側でデータを吐かせたというのも、コードを解析してそれっぽい変数を推測し、
吐き出させるためのコードを無理やり追加してやったという感じです。
ただ、当然ながら、変数の型(structの構造)は明らかになっているので、同様の型を
C++側にも用意してやれば何とかプロセス間でデータを受け渡しできるのではないかと思っています。
しかしここまでわからないことだらけの状況ではファイルを経由するのが現実的かもしれません…。
>>902 float * buf = malloc(sizeof(* buf) * 1024);
len = ReadData(a0, (void *) buf);
>>905 既存のロジックではファイルを出力しているの?
それだったらそこはそのまま使えばいいじゃん。
解析できないソースならシンプルがベストだよ。
実験してみてパフォーマンスに問題があるなら
その先を検討すればいいのだし。
>>905 ブラックボックスって言ってたけど、
もしかしてソースは有るの?
それともマシンコードを直にいじった?
>>908 後者のノウハウがあったらこんなぐだぐだな質問しないよ。
ただいまVisualStudio2008でC言語を学習しています。 サイン・コサインについて質問なのですが、例えば、 double angle = 0.0, answer = 0.0; answer = cos( angle ); という計算。angleに50を代入するとanswerの値は0.964966。 しかし、Windowsの電卓でcos( 50 )を計算すると0.642787…となり、値が全く違います。 これはどうやったら正確な計算ができるようになるでしょうか?
>>910 電卓のRadを選択してから計算してみ。
>>910 Windowsの電卓での 三角関数の引数の単位は 度 で受ける(デフォルト:ラジオボタン Deg がそれ)
C言語の 三角関数の引数の単位は ラジアン で受ける
つまり単位をあわせろ ということだ
>>910 関数の仕様をMSDN辺りできちんと読みましょう。
一般的に、角度の単位には度(°)ではなくradianが使われます。
>>911-913 なるほどラジアンでしたか…
もっとよく仕様を読んでみます。即レスありがとうございました。
あるテキストファイルに 「数字aを表示。」という文章が有り、 string にファイル入力し、 int a=256で宣言して、画面出力で 「数字256を表示。」と表示させる方法はありませんか? ゲーム製作中に主人公の名前等を変数に格納して 別ファイルにキャラの会話等を分割したいのです。 ソース内に台詞を全て直書きするほうが楽でしょうか?
>>915 テキストファイル内の $hero を主人公の名前 $heroine をヒロインの名前
のように置き換えるのがいいと思う
接頭辞+変数名+接尾辞 とか
>>916 それはファイル入力時に1文字ずつ読んで、接頭辞から接尾辞までを変数名
とする、みたいな入力をするということでしょうか?
918 :
デフォルトの名無しさん :2008/07/14(月) 17:38:10
>>915 テキストファイルで一行読み込んで、特定の文字が出たら
例えば
名前[0]を表示
[0] → [] + 数字 で 数字番目キャラの名前を表す って言うように決めておいて
[0]の部分を名前で置き換えればいいと思う
うは、被りまくりんぐ
テキストファイルに |"数字%dを表示。" 0 |"名前%sを表示。" 1 とかはどうよ? "で挟まれた区画は printf フォーマットそのもの 後ろの 0 や 1 を見つけて どの変数にするかを決める
Cで文字加工はめんどくさいからスクリプト言語に任せると楽かと。 const char * hero = "太郎"; sprintf(cmd, "/bin/sed -e 's/\$hero/%s/g' scriptFile", hero); FILE * fp = popen(cmd, "r"); fgets(buf, sizeof(buf), fp); pclose(fp); printf("%s", buf);
メンテ中のソースに出てきたらコメントアウトするレベル。
>>921 冗談だろw
「ゲーム」だと言ってるのに外部プロセスなんぞを
spawnして一体何フレーム待たせる気だ
やるならLuaあたりを埋め込むのがゲームのやりかたでしょう
>>923 >921をゲーム中でやると考える方がどうかしている。
んなもん、起動時に一回やればいいことだろうよ。
>>925 え?質問者の趣旨的には、
実行時の変数の状態に応じてメッセージの内容を生成したいわけだろ?
何言ってんだかさっぱりわからんが、酔ってんじゃねえの?
ヒント: 実行時なんて誰も書いていない。
ユーザーに名前を変えさせたいのか、開発時で登場人物の 名前が確定してないのか、どっちかな。 ゲーム中と書いてあるので、たぶん前者だと思うが。
ああよみちがい。 「ゲーム製作中」か
何か質問内容が不十分で誤解を生じていそうで申し訳有りません。
要は、
int main(){
string scr;
string name="主人公";
ifstream ifs("script.txt");
ifs>>scr;
}
テキストファイルscript.txtを用意
内容:
nameは死んでしまった・・・
これをprintfで表示した時に
出力:
主人公は死んでしまった・・・
を行いたいんです。nameはユーザーに入力してもらうつもりで、テキストファイルそのもの
を書き換えてしまうのはセーブを行う上で都合が悪いです。
>>928 前者です。
>>930 C++で書いてみた。入力文字列の $hero$ および $heroine$ をそれぞれおきかえるサンプル
#include <iostream>
#include <map>
#include <string>
void puts_var(std::map<std::string,std::string> var_map, std::string var_name){
std::string puts_string=var_name;
if(var_map.find(var_name)!=var_map.end()) puts_string=var_map[var_name];
std::cout << puts_string;
}
void puts_string(std::map<std::string,std::string> var_map, std::string target){
unsigned chk_start, var_start, var_end;
std::string var_name;
for(chk_start=0;(var_start=target.find("$", chk_start))<target.size();){
if((var_end=target.find("$", var_start+1))>=target.size()) break;
std::cout << target.substr(chk_start, var_start-chk_start);
if(var_end==var_start+1){chk_start=var_end+1;std::cout << "$";continue;} // $$ で $ 一文字出力
var_name=target.substr(var_start+1, var_end-var_start-1);
puts_var(var_map, var_name);
chk_start=var_end+1;
}
std::cout << target.substr(chk_start);
}
int main(void){
std::map<std::string, std::string> var_map;
std::string oneline;
var_map["hero"]="太郎";
var_map["heroine"]="花子";
while(getline(std::cin, oneline)){
puts_string(var_map, oneline);
std::cout << std::endl;
}
}
読んでないけど{$name}形式にしとけ。 終端が曖昧だとろくなことがない。
>>931 参照は嫌い?
というのは置いといて、istream作って変換しつつ読むほうがそれっぽいと思った。
934 :
931 :2008/07/14(月) 21:43:26
>>933 確かにistreamにした方がよさげですね
>>930 何文字目に"name"があるか探して、(n文字目)
前の部分(1〜n-1)を出力
変数nameの内容を出力
後ろの部分(n+4〜src.size())を出力
これだと最初の1つしか置換されないから、
後ろの部分からまた"name"を探して、
と見つからなくなるまで続ける
と、このレベルの質問なんじゃないかと思った。
クラスの宣言より後、定義より前のところでsizeof演算子を使うとコンパイルエラーになるのですが なんとかなりませんか?
こんな関数を考えましたが、うまく動きませんでした template<T t> int getsize(T t){ return sizeof(t); } どんな関数なら良いのでしょうか?
939 :
デフォルトの名無しさん :2008/07/14(月) 23:56:39
template<class T>だった
>>938 配列相手にうまくいかないというのなら、引数をconst T&にすれば動くと思う。
単にTだと、Tは要素へのポインタ型になるという規則があったはず。
ちなみに、配列を相手にしているなら、boost::sizeというものが既にある。
コンテナに使えばsize()を返すなどといった方向性での汎用化が進んでいる。
いや、配列じゃなくってクラスです boost::pool<> p(sizeof(T)) てなものを書きたくて
950踏んだら次スレ立て?
C#みたいにref xとか明示するようにしてればこんなに荒れなかった。 ハゲ言語実装者が悪い。
splintなら、hoge(/* out */ n); みたいなコメントつけないと警告でるとかって機能があったよね。 ちがうやつだったかな?
ref a = ref(b + ref c); ですね、わかります。
単項+演算子って何のためにあるんですか?
-の逆で、正を表現するためじゃないの?
そんだけですか? オーバーロードしてない単項+演算子が何かを起こしうる場合があれば教えて下さい
ByVal とか ByRef とか VB.NET らしくて良いですね
言語への質問になりそうなのですが、質問です typeofというものが、コンパイル環境によってあったりなかったりするのですが、 なんでVS2008にすら存在しないのでしょう? 「なんでって言われても、実装してないから実装してないんだよ」とかそんな返答を得そうな質問ですが あまりに不思議なもので typeof(data)::iterator it = data.begin(); ってかければどれだけ楽かと思うのですが…
951 :
デフォルトの名無しさん :2008/07/15(火) 11:33:53
C++でのファイルからのデータ入力について質問があります。 文字と数字が混在しているファイルから、それぞれを区別して読み取りたいときどうすればよいのでしょうか。 具体的には L 15 123 456 134 467 145 478 156 489 L 31 23 256 44 267 45 278 56 300 といった感じのデータがたくさんあり、"L"に続く数字がオブジェクトのID番号、 それ以下の行がオブジェクトの要素(具体的にはx,y座標)です。 ここから順次データを読んでいって、オブジェクトを生成しつつデータをセットする ということをしたいと思っています。 基本的で申し訳ないですが、教えていただけないでしょうかorz
>>950 C++の規格にはtypeofなんてものは存在しない
一部のコンパイラが独断と偏見で勝手に言語を拡張してるだけ
>>951 常に文字(列)として読み取り、それが数字であったならその文字(列)は数値に変換する
>>951 int a;
char b;
fscanf(fp, "%c %d", &b, &a);
C++の不幸は全てのClassに共通の唯一の祖先が無い事だと思う
不幸かなあ あえてそっちを選択したんじゃないの
>>950 C++0xのdecltypeあたりがきな臭いな。実験的にやってるコンパイラはあるのだろうな。
>>952 なるほど、VCは規格に厳密と。便利なので浸透してほしかったところですね
>>957 C++0x、いったいいつになったら来るんでしょうね('A`)そしていつ頃浸透するのやら
>>955 C/C++の理念として、何もしなければ一番早いモードになるってのがありますよ
だから共通の祖先をもって(つまり仮想関数を持つ祖先を持つという意味ですよね)しまうと、クラス関数呼び出しが仮想関数テーブル参照になってしまって遅くなるので避けたのでは?
>>957 decltypeっていう字面からは型を作りそうに見えるけどね
960 :
低脳 :2008/07/15(火) 15:07:19
VC9でtypeofが欲しいならBOOST_TYPEOFかなぁ。
>>959 int n1;
decltype(n1) n2;
ってことができるらしいよ
n2は当然intになる
便利だなぁこれ
いつからVCやBCBでそれが使えるようになるの?
auto it = data.begin();
VCは2008SP1で大きく変わるんだったか? BCBは・・・無理じゃねw
>>964 期待してVS2008でテストしたのに、未対応じゃねーか。・゚・(ノД`)・゚・。
予約語にはなっているようだが・・・(文字色が青にかわった)
auto int i; // == int i;
autoって自動変数の明示的宣言じゃないの?
ここは value でw
>>966 autoはもともと大昔のCの名残のようなキーワード。
ずるずるとC99/C++03でも残っているから当然青くなるわけだ。
C習いたての頃に律儀にregister int i;などと宣言して先輩に苦笑されたことを思い出した
今ここで見るまで存在を忘れていた>register
>>949 > ByVal とか ByRef とか VB.NET らしくて良いですね
ずれすぎ。
登録する関数を作ろうとすると地味にキーワードで困る>register この間は友人がfarを変数名に使おうとしてはまっていた
形容詞をそのまま変数名にしようとするのが間違い。
CのコードをC++でコンパイルしようとしてよく引っかかるのがnew
_register _far で大丈v
>>977 突っ込まれるの期待してるみたいなので、あえて突っ込まない。
>>977 MLB延長戦でそれどころじゃないので、あえて突っ込まない。
飯食って戻ってきたらまだやってたのかー
結局15回か。カズミア使わないでくれって言ってたのにしょうがないかw
char *p, c[] = "hogehoge"; p = c; printf("%d %d", (int)sizeof p, (int)sizeof c); こうやった場合 c のサイズが4バイトにならないのは何故ですか? c がc[]の配列の初めのアドレスを指すのなら と書いていたら何故だか分かりました、本当にありがとうございました
まずはぬいぐるみに話しかけてみろなんて話も聞くよね。
教わる時に使う頭と、教える時に使う頭って別なんだな 両方使うと理解が深まる、と
int c[] = {0x41, 0x48, 0x4F}; printf("%d", (int)sizeof c); さらに混乱すると
どこで混乱しようか
|::|::::l:::!:::/ \:::::: ヾ:::|::::::::| ::i::::1::リ:::: |: i:::::::::::::ゝ __ |::|::::|:::l::ハ|_ ヾ ::::::| ヽィ::::j/=、|::::::|::::7: /:::i::::| ____ \ :'´⌒ヽ |::ハ:::V:::| イ⌒゙`\:i リ \|ノ 弋_フノ /:::/: / |i " )_,,, _ l:ゝ::.\::i〃⌒゙ヽ 〃⌒゙ヾ //::) | 'ハ::::: | コ た や |i ヽ | ト/人7} 〃〃 〃〃´ ∠イr 'ちノ::::: | ン え っ |i / ・ i イ:リ::::| '、 |:::::rイ:::::::: | パ ち た |i t / i:::::ハ r‐--ー、 /ハi!:::::::::::::::: | 通 イ ゃ ね |i 〃 ● ハ::::::: \ .イ_ _,,ツ イ/'/:::::::::::::. < っ ル ん |i r一 ヽ ) /i::ハi::::i:::::>,, ___ _,, ´ /,,ハ/|/:::ii:::::::: | た が ! |i | i ∀" "  ̄ ̄ ト、 //ヽ  ̄" ̄ | よ |i | i ノi ノ:r j :ア` …‐: | |i ニ| |二二◎ __,..'| / / :::: | |i i i ヽ __,,:'´ t/ / :: | li } ,_:'´ { ,,___ / ,,/i \____
ああ、次はコアダンプだ‥‥
>>991 いえいえ、遠慮していただいて結構ですよ。
993 :
デフォルトの名無しさん :2008/07/16(水) 21:55:37
埋めるか?
>>984 ああ、だからフィギュアが置いてあるのか!
インクリメント
俺はsizeofに括弧を付ける派
じゃあreturnにも括弧付けるんだね
returnは単独で文になるからつけないが、 sizeofは要素にしかならないからつける派
うめますか
うめます
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。