[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2chのread.cgiへ]
Update time : 11/14 14:36 / Filesize : 194 KB / Number-of Response : 757
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【初心者歓迎】C/C++室 Ver.39【環境依存OK】



1 名前:デフォルトの名無しさん [2007/06/25(月) 12:01:46 ]
エスケープシーケンスやWin32APIなどの環境依存な物でもOK。
ただしその場合、質問者は必ず、環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。
【前スレ】
【初心者歓迎】C/C++室 Ver.38【環境依存OK】
pc11.2ch.net/test/read.cgi/tech/1180877635/
【アップローダー】(質問が長い時はココ使うと便利)
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm

333 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 17:20:35 ]
>>329
cout << static_cast<std::string>(a);
とやるか、
std::ostream& operator<<(std::ostream& os, const A& a) { return os << a.x; }
でも定義汁

334 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 17:28:57 ]
皆様の回答を参考にぐぐったら出てきました
ttp://www.higlab.k.dendai.ac.jp/~numata/index.php?C%2B%2B%A5%E1%A5%E2#w5403b76
なるほどオーバーロードとfriendの複合技ですか、さらにostreamを戻す事で連結も可能と…
かなり使えそうな方法ですね、助言ありがとうございました!

335 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 17:40:54 ]
>>334
ここまで必要になるか分からないけど、

class A {
public:
 virtual void print(std::ostream &os);
};
std::ostream& operator<<(std::ostream& os, const A& a) { a.print(os); return os; }

とやった方が、もしかしたらいいかもしれない。
こうすると継承クラスでprintを再定義できる。

336 名前:334 mailto:sage [2007/07/01(日) 18:02:45 ]
>>335
なるほど継承ですか、実行時の多態性については意識し取りませんでした
確かにこの振る舞いをもたせたいのがAだけに限るわけではないですしね
とりあえず参考にしてNVI使ってこうやってみました

// 構造体A周辺の定義
struct Base {
public: void print(std::ostream& os) const { _print(os); }
private: virtual void _print(std::ostream& os) const =0;
};
struct A : public Base {
private: void _print (std::ostream& os) const { os << x; }
public: int x;
};
std::ostream& operator<<(std::ostream& os, const Base & base)
{ base.print(os); return os; }

// 使用例
#include <iostream>
int main() {
    A a;
    a.x = 1;
    std::cout << a;
}

…しかし鶏を捌くのに牛刀をなんとやらですね
実際に使うとなればここまでする必要も出てきそうな気もせんでも無いですが

337 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 18:27:37 ]
この場合のNVIって何の意味があるの・・・?

338 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 18:29:47 ]
最近おぼえて使いたくなったんだろ。気にするな。

339 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 18:35:35 ]
NVI
ってなんですか?

340 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 18:40:11 ]
>>339 ググレカス

341 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 18:49:35 ]
NVI=non virtual interface のこと。つまり↓
struct Hoge {
 void hage(T1 arg1, T2 arg2) {_hage(arg1, arg2); }
protected:
 virtual void _hage(T1 arg1, T2 arg2) = 0;
};
下位クラスには_hageを継承してもらう。

なぜこんなことをするのか)
公開仮想インターインターフェイスが果たす目的は以下の二つ(と言われてる^^)
 1. 使う人に使い方(インターフェイス)を提供する
 2. 派生クラスに「こういうふうにメソッドを継承して下さい」とカスタマイズの規約を提供している

たとえば、NVIを使わず下位クラスがhageをそのまま継承してしまうと
Hoge#_hageのインターフェイスを変更したときに下位クラスすべてのメソッドを書き直す必要があるんだけど、
もしNVIを採用していればそういうことにはならない。
逆にインターフェイスを変更せず、実装メソッドの方だけを変更することもできる。

>>336の場合、インターフェイスが変更される可能性は全く無くて、無駄に複雑にしてるだけだと思う。



342 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 18:52:31 ]
そもそも値型のクラスの継承はあまり宜しくない

343 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 18:54:58 ]
値型のクラス???

344 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 19:11:16 ]
Value classの事
・publicなデストラクタとコピーコンストラクタと代入演算子を持ち
・デストラクタを含め仮想関数を持たなくて
・具象クラスであり抽象クラスでない
・スタック上や他のクラスのメンバとしてインスタンス化される
とまぁおおよそ組み込み型のように振舞えるものでこういうのは継承じゃなくて委譲を使うべきらしいけど、
実際のところはそれが妥当なのか場合によるからよくわかんねけど
俺は複雑な構造体を継承してえらい目にあったので「あまり宜しくない」と思うようになった
ちなみに出展はmore effective C++あたりだったと思う

345 名前:341 mailto:sage [2007/07/01(日) 19:23:42 ]
>>344
Value classなんて初めて知った。
全部が全部ってわけじゃないけど、ほとんどは>>344のいうとおりだろうね。

ただ、サンプルプログラムでそういうことを考えちゃうと
バーチャルなデストラクタや、privateなoperator =を書く必要が出てきて
全体的に焦点がぼやけてしまいまふ。
>>341ではとりあえずそういうことは無視させてもらいますた^^

346 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 19:29:32 ]
>>344
そんな区別意味無いだろ。
public なデストラクタが virtual じゃないクラスを継承したのが間違いだったんじゃないの?

value class って用語も検索結果が日本語ページ多すぎで胡散臭いし。

347 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 21:00:20 ]
値のセマンティクスを持つクラスと言いたいのでは?
ググったらこんなページを見付けたが、こういう話だろう。
www.ogis-ri.co.jp/otc/hiroba/technical/CppDesignNote/

348 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 21:09:43 ]
つうかそういうクラスはそもそも継承を前提に作ってないだろ

他言語ならsealedクラスになってるタイプのクラス

349 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 21:29:11 ]
>>342に戻ると
良いサンプルってやっぱ難しいんだね

350 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 21:33:35 ]
複雑なものを扱うためのテクニックを簡単なサンプルで見せても
無意味にしか見えんからのう

351 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 22:17:49 ]
とりあえず、NVIならこの程度のサンプルでも十分通用するね



352 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 22:18:38 ]
NVIってExceptional C++で勉強しましたか?

353 名前:デフォルトの名無しさん mailto:sage [2007/07/01(日) 22:22:03 ]
Exceptional C++―47のクイズ形式によるプログラム問題と解法
Exceptional C++ Style―40のクイズ形式によるプログラム問題と解法=スタイル編 Exceptional C++ Style―40のクイズ形式によるプログラム問題と解法=スタイル編

これって何が違うんでしたっけ?

354 名前:デフォルトの名無しさん [2007/07/02(月) 00:12:21 ]
4バイトint型 num = 10,000,000の16バイト表現を、
ビッグエンディアンで
char型 d[10]のd[5]〜d[8]の各要素に格納したいと思っております。

numを表現する4バイトそれぞれの値を取得するためには
どうすればいいのでしょうか?
char *p = (char *)num; // numのポインタを取得
d[5] = p; // 1Byte分の値を取得
p++; // charのポインタなので1Byte分ポインタを変更
とやることを考えたのですが、pの値がおかしな値になります。

どのようにコーディングするとよいでしょうか?


355 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 00:14:59 ]
char *p = (char*)#
の間違いだと思うのだがどうよ

356 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 00:17:24 ]
たびたび、すみません。
スレッドに複数の引数を渡したい者です。

//スレッド関数
void Thread_f(void* StructData){
 //何にもしないスレッド StructDataは、下で出てくるData構造体
}

メインのほうで、スレッド作成
Data data; //Dataっていう複数の引数を渡すための構造体
for(int i=0;i<n;i++){
  data=datalist[i];//datalistは、Data構造体のポインタ配列 代入してから渡してます
  handle[i] =(HANDLE) _beginthread(CameraThread,0, (void *)&data);
  Sleep(3000); i++;
  //スレッド立ち上げてる間に、全部スレッド側で全部datalist[n]になってしまうので。
  //ちょっとSleepしました。すごいダメな処理です。すみません。 
}
n=1のときは、エラーでないです。
nが2より大きいと、動くことは動きますが、×(ウィンドウの閉じるボタン)
で閉じると、
-ElnvalidPointerクラスの例外を生成しました。
-'無効なポインタ操作'
-プロセスは停止しています。・・・・
というエラーがでます。
”同じポインタを 2 回破棄したり,すでに破棄したポインタを参照したりすると出る”
とネットの掲示板でありました。

同じ関数のスレッドに、それぞれ違うdataを渡したいときは、スレッド関数に引数渡さないほうがいいですか?
248さんが言ってたのは、このことかなぁと思って、今は、引数渡さない方法でやってますが。

上記のプログラムに、手を加えてエラーで無い方法ないでしょうか。

357 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 00:21:55 ]
あっ、CameraThreadは、ほんとの関数名でした。
Thread_fに、訂正お願いします。

358 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 00:23:23 ]
>>356
だから、スタック上のオブジェクトのポインタをスレッド関数に渡すなと。
呼び出し側のコンテキストが平然と進行しつづけてスコープ抜けた瞬間に
無効になっちゃうだろが。

malloc()やnewでフリーストア上にオブジェクトを確保して、その
ポインタを渡すんだな。無論渡されたスレッド側で不要になったら
破棄すること。

本当はC++使ってるんなら、スレッドをラップするクラスを作るのが良いが
それはまあいい。

359 名前:354 [2007/07/02(月) 00:23:58 ]
>355
ご指摘どおりです。
char *p = (char *)# // numのポインタを取得
d[5] = *p; // 1Byte分の値を取得
p++; // charのポインタなので1Byte分ポインタを変更
d[6] = *p;
p++;
・・・

としているのですが、値が正常にとれません・・・


360 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 00:32:53 ]
>>358
レスありがとうございます。
new演算子は、Dataをでしょうか?
Data *datalist = new Data[N];
これで処理してます。

361 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 00:34:23 ]
>>360
それなら、そのdetalistをそのまんま(void*にキャストして)渡せばいい



362 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 00:42:56 ]
>>361
data=datalist[i];
これを、なくして
handle[i] =(HANDLE) _beginthread(CameraThread,0, (void *)&datalist[i]);
ということですよね。
これでも、同じ症状です。

dataにコピーしてから、渡すとエラーが消えるかも、
と思って入れたおまじないの処理なんです。

363 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 00:46:27 ]
>>362
ちょっとまて
意味わかんなくなってきた

スレッドをN個起動してて、i番目のスレッドにdatalist[i]を渡したいのか
だがそれだと、datalist[]の破棄はどうする?
いつどこで誰がやってるんだ?

364 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 00:48:21 ]
今日ここで俺がやる

365 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 00:55:11 ]
メインの方で、スレッドの処理が終わるのを、待ってからです。

スレッドが終わるまで待ちます。
for (int i=n; i>0; i--){
 while(WaitForMultipleObjects(n, (CONST HANDLE *)handle,TRUE, 500) == WAIT_TIMEOUT){//タイムアウトなのでループ}
}
delete data;

366 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 00:57:35 ]
>>365
datalist じゃないのか? delete [] じゃないのか?

367 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 01:03:11 ]
>>365
その i でまわしてる for ループは何のつもり?
WaitForMultipleObjects() で全部待つんだろ?
あと、戻り値はちゃんとチェックしろよ。

(CONST HANDLE *) とかいうキャストも要らんだろ?
っていうか前のコードから要らないキャスト多すぎだ。

368 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 01:04:02 ]
お手数かけてすみません。
delete datalist;
です。

369 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 01:04:48 ]
>>365
よくわからんが、メモリバリアを_beginthreadex()の前後あたりに
挿入すると状況が改善されるかも

370 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 01:05:24 ]
>>368
それじゃダメだ。 delete [] 使え。理由は聞かずにちょっと前のログを見ろ。

371 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 01:27:44 ]
while(WaitForMultipleObjects(n, (CONST HANDLE *)handle,TRUE, 500) == WAIT_TIMEOUT){}
スレッドが終わったっていう合図以外は、ここでループしてます。
タイムアウト以外というコメント不正確でした。
forで、n回繰り返すと、n個のスレッドが終了するのを待ったことになります。



delete datalist [];
deleteの使い方理解していないので、
ちょっと時間掛かるかもです。構文エラーとか出てきます。



372 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 01:29:11 ]
構わんよ、おつまみみたいでみんな喜んでるみたいだし

373 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 01:29:40 ]
delete [] datalist;
ああ、反対でした。
同じエラー出てきました。


374 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 01:36:17 ]
>>371
> forで、n回繰り返すと、n個のスレッドが終了するのを待ったことになります。

WaitForMultipleObjects() の第3引数は BOOL fWaitAll で TRUE の時は
その呼び出しで全部待つ。戻り値にはエラーもある。仕様をちゃんと見て使え。

375 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 01:43:53 ]
delete [] datalist;
コンパイル通りました。

-ElnvalidPointerクラスの例外を生成しました。
-'無効なポインタ操作'
-プロセスは停止しています。・・・・

やっぱり、これが出てきてしまいます。。。
スレッド1個(n=1,N=1)にすると、大丈夫なんですよね。

あと、>>356で、Sleepの次i++が入ってまずが
頭がおかしくなって、入力してしまったのかもしれません。
すみません。

376 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 01:47:27 ]
疲れてるなら休めば?スッキリしてないと頭の回転悪いよ

377 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 01:51:18 ]
ぶっちゃけそのレベルで
メダパニとラリホーかけられてちゃ
どんな間違いやってても不思議じゃないな

378 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 02:02:34 ]
>>374
ありがとうございます。
WaitForMultipleObjectsで、苦労したんですが
なんか思い出だしてきました。


結局、スレッドの方では、なんにもしてないので、
newで渡すのがだめな気がしてきました。

379 名前:378 mailto:sage [2007/07/02(月) 02:14:02 ]
今日は、ちょっとギブアップします。
ありがとうございました。

380 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 09:25:30 ]
>>315
間取ってC++Builder使えばいいんじゃね?

381 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 09:42:53 ]
>>332
A内でfriend宣言しておかないとA.aのように参照した場合
もしaがprivateやprotectedだった場合エラーになる。



382 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 09:55:23 ]
>>381
この場合はstructで全部publicだから要らんと言われてただけでしょ

383 名前:378 mailto:sage [2007/07/02(月) 10:18:40 ]
378です。
シンプルなプログラムを別に作って、
new演算子でも大丈夫なこと確認しました。

それで、本物の方のプログラムの方をGUIの部品とか
1個ずつはずしていって、シンプルなプログラムに近づけていったところ。。。
(6時間後・・・)

void __fastcall TForm1::Button17Click(TObject *Sender)
{
//なにもしないボタンです。これから実装します。
}
ボタン17を削除して、またボタン作ったら
なぜか閉じるボタンで、ポインタエラーがでなくなりました。
ということで、new演算子で渡しても大丈夫みたいです。
ありがとうございました。

384 名前:デフォルトの名無しさん [2007/07/02(月) 13:07:16 ]
VC7でswitch内で

 switch (val)
 {
//コメント
 //コメント
 case 1:
  〜〜
  break;
 }

こんな感じでcaseの上に複数コメントがあるブロックが多いと、
デバッグの時のブレークポイントや、実行時の位置が
おかしくなることがあるみたいなんですが、どこかに詳細な
報告はありませんか?
検証が甘いですが、VC2005でも同じ現象が起こるみたいです。

385 名前:デフォルトの名無しさん mailto:sage [2007/07/02(月) 14:12:08 ]
int (*a)[] = new int[10];

386 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 17:39:39 ]
質問です。

Foo::Foo() : m1(), m2(), m3() {}

このようなFooクラスのコンストラクタにおいてm2のコンストラクタが例外を投げたとき、
既に初期化が完了していたm1のデストラクタが呼ばれることは「C++の規格で保障」されているのでしょうか?

VC++2005で確認した限りではその通りの動作をするようですが…


387 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 17:44:42 ]
保証されてる。

Foo::Foo() try : m1(), m2(), m3() { } catch(...) { }

みたいにしてキャッチすることもできるけど、
例外は必ず再送出される。

388 名前:386 mailto:sage [2007/07/03(火) 17:51:16 ]
>>387
ありがとうございます。

> Foo::Foo() try : m1(), m2(), m3() { } catch(...) { }
そういえば function-try block なんて見たのは久々^^;


389 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 18:04:46 ]
コンストラクタが失敗して例外を投げたときって、
中途半端にコンストラクトされた状態だと思うんだけど、
デストラクタは呼ばれないわけだよね?
メモリリークの原因にならないのかな?

390 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 18:07:50 ]
if(pMem){ delete pMem; }
でおk

391 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 18:09:32 ]
>>389
ちゃんと自分で例外をキャッチして開放してくだちぃ。
それが嫌なら vector とかスマートポインタとか使ってデストラクタに任せてくだちぃ。



392 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 18:12:42 ]
>デストラクタは呼ばれないわけだよね?
catchしたら呼べばいいじゃん。

393 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 18:12:52 ]
>>390
deleteはNULL渡したら勝手に無視してくれなかったっけ?

394 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 18:13:12 ]
してくれる。

395 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 18:13:59 ]
仕様上は無視することになってるが、
昔の VC++ あたりはしてくれなかった記憶がある。

396 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 18:20:11 ]
そうだっけ?
もしそうなら、そのときはその仕様がまだなかったんじゃないか

397 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 18:21:03 ]
www.google.com/search?hl=ja&q=directx+if+delete+release&lr=lang_ja
なんてググると、DirectXあたりで
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
こんなマクロが出てきたりするからてっきり勘違いしていた。

398 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 18:24:56 ]
>>396
VC6 あたりまでそうだったと思う。
この仕様があるかどうか微妙な時代かもしれん。

399 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 21:20:22 ]
SAFE_DELETEの利点は変数にぬるぽを代入してくれる点

解放後にアクセスしようとすると素直に落ちてくれる

400 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 21:28:18 ]
ニートで暇だからプログラミングの練習でもするかとゲームを作り始めたのですが
いきなり挫折しました。かれこれ4時間ほど睨めっこしてるのですが
どこに間違いがあるのか検討つきません。ご教示お願いします。

環境はコンパイラはBoland C++ 5.5 + BolandDeveloper 1.221
WinアプリケーションでDXライブラリです。(多分環境は関係無いんでしょうが)

メッセージはint型はchar *型に変換出来ないと出ます。

一部抜粋
FILE *fp;
char *file_name="map1.txt",buf[99];
char* p;
char* q;

if((fp=fopen(file_name,"r"))==NULL)return-1;

このぎょうです。→ while((fgets(buf,sizeof(buf),fp))!=EOF){
j=0;
p=strtok(buf,",");
map_data[i][j]=atoi(p);
j++;
while(p!=NULL){
p=strtok(NULL,",");
if(p!=NULL){
map_data[i][j]=atoi(p);
j++;
}
}
i++;
}
fclose(fp);

401 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 21:32:58 ]
とりあえず、fgetsはEOFなんか返さないってば。



402 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 21:39:19 ]
>>401
ありがとうございます。
・・・orz

混乱していたから別ファイルで作ったのを
コピペ改変していました。

なんでこんなミスばっかりやらかすんだろな・・。俺は。

403 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 21:39:50 ]
だからニートなんだろ

404 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 22:38:48 ]
すみません。mallocって確保したメモリのポインタが返ってくるのですが、
このポインタって確保したメモリのどこを指しているのですか?
このポインタ指しているところの規定ってあるのですか?あればどんな規定?

405 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 22:42:38 ]
>>404
最初(0アドレス)を指してる。

406 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 22:47:07 ]
0アドレスって凄い誤解されそうな・・・。

407 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 22:49:05 ]
char *p = malloc(size); とすれば、

p[0] 〜 p[size - 1] のメモリをアクセスできることが保証され、
p + size が無効なアドレスにならないことが保証されている。

408 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 23:27:47 ]
何となく思ったことなんですが、
char *s = "hoge"; は
char s[] = "hoge"; と違って、中身を書き換えたりしたらダメなんですよね。じゃあ、最初から
const char *s = "hoge"; としておいた方が、間違って書き換えちゃったりしたらコンパイル時にエラーになって、
深夜のデバッグ作業突入を防げるような気がするんですが、これはいい考えですか?
それとも、気をつければいいだけですか?

409 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 23:30:13 BE:223773825-2BP(21)]
>>408
とてもいい考えアル
と、effective c++あたりに書いてあった希ガス

410 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 23:37:22 ]
>>408
char *s = "hoge";
char s2[] = "hage";
s = s2;
s[1] = 'i';

constをつけるとこれもできなくなる。やらないと思うけど。

411 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 23:43:50 ]
const char* const s ="hoge";

にすれば
s++
とかも防げるぜ!



以下修飾子の位置について終わりのない議論が始まります



412 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 23:45:27 ]
>>408
少なくとも自分は条件反射的にconstつけてる

413 名前:デフォルトの名無しさん mailto:sage [2007/07/03(火) 23:46:11 ]
結論出たので終了

414 名前:デフォルトの名無しさん [2007/07/04(水) 01:05:17 ]
今日wstring型ってのを知ったのですが、
  wstring a[2];
  a[0] = L"あああああ";
  a[1] = L"いいいいい";

  wcout << a[0] << endl;
  wcout << a[1] << endl;

ってやっても何も出力されません。
なぜでしょうか?教えてください。
ググっても良い資料が見つからない、、、。

415 名前:デフォルトの名無しさん [2007/07/04(水) 01:06:39 ]
>>414です。
”何も”ではなく空白行が2行出力されます。

416 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 01:07:36 ]
wcout locale imbue
でググるんだ!

417 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 01:23:30 ]
string

418 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 01:25:59 ]
横レスだが、MacOSX GCC 4.0.1 だと locale に何渡しても runtime_error になるな。

419 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 01:53:39 ]
Javaの静的初期化メソッドみたいなもの、C++にありましたっけ?
たとえば、

class hoge {
static int num[100]; //この配列を0-99まで初期化したい
}
hoge::int num[100];

といったとき、どう書くのが一番スマートですか?
(num[100]={0, 1, 2...} とやるのはなしとして)
コンストラクタ内で初期化しようとすると
インスタンスを生成するたびに何度も同じ処理が
繰り返されることになるので無駄だし……
初期化処理が既に終わっているかどうかを示す
フラグを追加するとかでしょうか。

420 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 02:04:49 ]
今考えたけど、こういうゴリ押しができなくもないな。
friend しなくても通ったけど、これって規格的におkなの?

#include <iostream>

class hoge {
private:
static const int SIZE = 10;
private:
struct static_init {
static_init() {
for(int i = 0; i < SIZE; ++i) {
num[i] = i;
}
}
};
public:
static void show() {
for(int i = 0; i < SIZE; ++i) {
std::cout << num[i] << std::endl;
}
}
private:
static int num[SIZE];
static static_init static_init_;
};
int hoge::num[hoge::SIZE];
hoge::static_init hoge::static_init_;

int main() {
hoge::show();
}

421 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 02:17:42 ]
この程度で充分じゃね?
class hoge {
 static int num[100];
};
int hoge::num[100];
static int initialize() {
 for (....) {
  ...
 }
}
static int initializer = initialize();

ファイルスコープのstaticが嫌いならnamespace{}でも。



422 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 02:24:58 ]
関数を friend にする必要があるね。
個人的には戻り値 int が必要になるのが気持ち悪い。

423 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 02:36:10 ]
>>421
うわー、その手がありましたか。
絶対忘れないように今すぐそれ使って何か書いてきます。
ありがとうございました。

424 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 02:56:23 ]
class CStaticInt
{
public:
  CStaticInt(void)
  {
    for( int i = 0; i < 100; i++ )
       a[i] = 0;
  }
  ~CStaticInt(void){}

  static CStaticInt* GetInst( void ) {
    static CStaticInt obj;
    return &obj;
  }
  int a[100];
};

こういうのもどう?
んで、CStaticInt::GetInst()->a[0]でアクセスする
マクロ化すれば使用に耐えられなくも無い…かもしれん('A`)

425 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 12:45:31 ]
scanf("%s",str);
if(strcmp(str," ")==0)
printf("空白文字");
これで入力された文字が空白かどうか調べようとすると
strcmpが0とならずprintfが実行されません。
これってどこがダメなのでしょうか?


426 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 12:47:49 ]
>>425
入力が半角空白1文字じゃないんだろう。
else で puts(str) してみれば?

427 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 13:02:37 ]
>>426
う〜ん、なんか動かしてみると
scanfが空白文字を読み込んでないみたいな動作をするというか、
半角空白を入力すると入力が終了せず延々と入力を促すようになるのです。
だからif文の後もelse文も実行されない感じでしょうか。


428 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 13:11:21 ]
%s は空白を飛ばすから当然そうなる。

429 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 13:16:38 ]
>>428
そうなのですかorz
では文字列を入力するという処理で空白文字が入力されたか
というのを調べるには↓みたいにするしかないですか?

fgets(str,N-1,stdin);
if(str[0]==' ')
printf("空白文字");

430 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 13:20:54 ]
strstr()


431 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 13:42:00 ]
>>429
どういう仕様にしたいのかが今ひとつ分からんから何とも言えんなあ。
" hoge " とか "hoge hoge hoge" とか入力された場合どうしたいのかな?



432 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 14:08:13 ]
>>431

char str[N][N];
int i;
for(i=0;i<MAX;i++){
printf("文字列入力:");
fgets(str[i],N-1,stdin);
if(str[0]==' ') break;
}

こんな感じで空白文字が入力されたら入力を打ち切る仕様にしたいのです。
だから"hoge hoge hoge"の場合はそのまま文字列として格納です。

>>430
紛らわしいこと書いてすみません、仕様は上記のような感じでした。

433 名前:デフォルトの名無しさん mailto:sage [2007/07/04(水) 14:10:00 ]
if(str[i][0]==' ') break;
でした。書き間違い。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<194KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef