- 1 名前:デフォルトの名無しさん mailto:sage [2010/01/29(金) 23:15:45 ]
- エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。 ※sage禁止です(と代々スレに書いてありますが自己判断で)。 【前スレ】 【初心者歓迎】C/C++室 Ver.70【環境依存OK】 pc12.2ch.net/test/read.cgi/tech/1258873470/ 【アップローダー】(質問が長い時はココ使うと便利) kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm codepad.org/ (コンパイルもできるし出力結果も得られるのでお勧め) ◆ソースのインデントについて 半角空白やTABでのインデントはスレに貼ると無くなります。 そのため、アップローダーに上げるのも手ですが直接貼る場合は、 全角空白か に置換すると見栄えだけはよくなります。
- 573 名前:デフォルトの名無しさん mailto:sage [2010/02/17(水) 22:13:46 ]
- コンストラクタ
- 574 名前:デフォルトの名無しさん mailto:sage [2010/02/17(水) 22:44:09 ]
- STLを使うならEffectiveSTLには絶対に目を通しておけ
- 575 名前:572 mailto:sage [2010/02/18(木) 01:18:05 ]
- >>573
コンストラクタに(const char* )を追加して実行してみました. ttp://codepad.org/8ai16KPo どうやら大分ひどいことをしているようなんですが, コンパイルは通ってしまいます. ご指導をよろしくおねがいします. もしくは>>574さんの勧める書籍を読めば何故こうなるのか理解出来るでしょうか?
- 576 名前:デフォルトの名無しさん [2010/02/18(木) 01:21:03 ]
- クロージャで出来て関数ポインタで出来ない例が思いつかない。
- 577 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 01:32:58 ]
- >>575
暗黙定義のコピーコンストラクタと代入演算子で浅いコピーになってる。 デストラクタを書くようなクラスではこの2つも必ず確認しなければいけない。
- 578 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 01:47:45 ]
- >>576
関ポじゃ状態を持てないじゃん
- 579 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 02:01:11 ]
- >>575
codepad.org/kAeUsq2i これでいいと思われます 要するにクラス内部でnew/deleteを行うような場合は 必ずコピーコンストラクタと代入演算子関数は自前で用意 しなければならないという事です そうしないとクラッシュしたり、メモリリークしたりします
- 580 名前:572 mailto:sage [2010/02/18(木) 02:59:22 ]
- >>579 >>577 ありがとうございます!
コピーコンストラクタと代入演算子を作らないといけなかったんですね わかりやすくコードもひいてくださりありがとうございました
- 581 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 08:36:28 ]
- >>579
operator= の new で失敗するとゴミポインタ持ったままのインスタンスが残っちゃうよ。 delete の前のヌルチェックは要らないよ。(メッセージを分けたかったんなら別だけど) strlen() してから strcpy() するのってもったいないね。 date() じゃなくて data() だよね?(あ、 >575 から間違ってるのか。) こんなちっちゃいクラスでもこんだけ問題が出るんだから、やっぱり自作文字列クラス なんて作るもんじゃないね。みんなわかってると思うけど。
- 582 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 09:51:30 ]
- >>578
やっと理解した。Cというか関数ポインタだと代替にならないな。 でもこれC++ならクラスでやれって話になるな。
- 583 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 10:18:58 ]
- 乱暴に言うと、クラスはデータとそれに付随する振る舞いをまとめたもの。
クロージャは振る舞いとそれに付随するデータをまとめたもの。 ・・・っていうのはどの本の説明だったかな。
- 584 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 10:38:06 ]
- データ構造を決めれば操作は大体決まるから
俺にとっては前者のほうが自然に感じるが 一方、振る舞いだけでデータも記述できるんだよな 抽象データ型とかは操作ありき、だし object is a poor man's closure closure is a poor man's object
- 585 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 12:11:05 ]
- クロージャって要は関数オブジェクトみたいなもんでしょ?
- 586 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 12:45:33 ]
- >>581
>delete の前のヌルチェックは要らないよ。 デタラメ言うんじゃないよ 代入前に既に値が入ってたらどうするつもりだ それともtextが0だったらdeleteしても何も起きないというつもりか それだったら個人の自由だ プログラム上値が入っていたら消すんだよという意味を強調している それから >operator= の new で失敗するとゴミポインタ持ったままのインスタンスが残っちゃうよ。 文句言うなら自分でもっといいプログラム貼れや >strlen() してから strcpy() するのってもったいないね。 >date() じゃなくて data() だよね? 元のプログラムをそのまま使っただけだ 自分が1から書いたらもちろんこういう書き方はしない もう一度言う 文句あるなら自分で貼れ
- 587 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 13:20:25 ]
- >プログラム上値が入っていたら消すんだよという意味を強調している
んなの強調して何の意味が。deleteなんだから消すに決まってる。 「値が入っていたら」はdeleteがやってくれる。
- 588 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 13:24:06 ]
- delete null 規格上は許されてるよ。
でもまあ、nullチェックしたほうが自然だろな。
- 589 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 13:29:38 ]
- そのnullチェックがそのコードで意味があってのことならやるが
機械的にチェックするだけ、という意味しかないのなら消すわ
- 590 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 13:34:14 ]
- if(p) Delete(p);
void Delete(Obj *p) { if(p) _Delete(p); } void _Delete(Obj *p) { if(p) __Delete(p); } ・・・
- 591 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 13:45:25 ]
- 上の実装だと内部データ返せるから
dateの戻り値をdeleteだって出来る(これは設計ミスだろう)。 そうなるとチェックせずにdeleteするのは「二重delete」で死ぬと思ったんだが ノーチェックで問題ないんかえ?
- 592 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 13:47:07 ]
- は?NULLチェックするに決まってるだろ
んでdelete後にはNULL入れとけボケ
- 593 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 13:53:36 ]
- 俺は暗にあんたを擁護したんだが・・日本語勉強しる
- 594 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 14:05:06 ]
- ID出ないと誰が誰だか分からない
まあとりあえずみんな落ちつけ
- 595 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 14:06:13 ]
- なんでID無しなんだろうな
おかげで自演し放題だわ
- 596 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 14:44:11 ]
- ●持ちには隠しID丸見えだよ
自演はほどほどに
- 597 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 14:54:03 ]
- あちゃー、このスレ全部俺だったのバレてたか
- 598 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 14:58:48 ]
- いやいや、俺俺。
- 599 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 15:11:47 ]
- >>591
「deleteしたらNULL入れる」だけで二重deleteは防げる。 NULLチェックしたって二重deleteは全く防げない。
- 600 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 16:11:57 ]
- >>599
C++は規格票でもNULLより0が推奨されています
- 601 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 16:35:47 ]
- もう>>498はいないだろうが
n行m列のvectorの二次元配列の確保で vector<vector<int> > v(n,vector<int>(m)); こういう書き方って異端?
- 602 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 16:55:40 ]
- >>601
別に 三次元の場合もその書き方でよく書いてるけど
- 603 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 17:49:15 ]
- 異端じゃないけど効率悪いよ
n*mサイズのベクタ一本とってインデクスは計算で出すほうがいい つーかC++は効率を良くしつつv[a][b][c]=1;みたいに書くことができないのが残念 せめて[a, b, c]とかでもいいからoperator定義できればよかったんだが
- 604 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 19:27:19 ]
- >>602
なるほど、了解 >>603 >n*mサイズのベクタ一本とってインデクスは計算で出すほうがいい 直感的にはループの中で剰余と割り算でインデックス計算したりするほうが 遅くなるように思うけど 領域が連続でないことでそんなに遅くなるもん?
- 605 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 19:30:37 ]
- >>604
連続でないってことは内部的に管理する仕組みが動いてるだろうから インデックスの増減ですぐにアクセスできるのとでは消費パワーが違うよ
- 606 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 19:58:58 ]
- (n, m)のインデックス算出に剰余と割り算使うのか?
普通はかけ算と足し算だと思うが
- 607 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 19:59:25 ]
- >>604
剰余も割り算も使わないよ v[siz1 * idx2 + idx1] 乗算と和だけ あとベクタのベクタはメモリに関するコストが増える
- 608 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 20:01:36 ]
- kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10537.c
クイックソートを再帰なしに作ったんですが,なぜかソートされません・・・なぜorz
- 609 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 20:17:17 ]
- >>605-607
確かにorz 自分の勘違いも含めたベンチコード codepad.org/FTA8SWtA vectorにしたら結果が大きく変わるってことはないと思うんで 思ったほど差はない模様
- 610 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 20:52:26 ]
- >>608
まずpartitionがうまく動いてるか調べてみたら?
- 611 名前:569 mailto:sage [2010/02/18(木) 22:35:34 ]
- >>571 レスありがとう.
boost::operators 調べてみたけど,クラスに operator を自動追加してくれるだけで 関数オブジェクトには利用できないのかな? ソート対象のメンバ変数ごとに Less の関数オブジェクト用意して, 逆順ソートする場合は Less の関数オブジェクトから Greater の関数オブジェクトを生成して ソートに利用する手法は良くやりそうだけど,自分で作るしかないか…
- 612 名前:デフォルトの名無しさん mailto:sage [2010/02/18(木) 23:01:17 ]
- #if defined(Q_WS_MAC)
何これ?
- 613 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 00:34:01 ]
- #define TEST 5でマクロを定義し、char型の配列等に文字列TESTを代入すると、
"5"が判断されなくなってしまいます。 マクロを文字列に代入し、尚且つ置き換え後の値を取り出すにはどうしたらよいのでしょうか?
- 614 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 00:53:02 ]
- こんな感じの??
codepad.org/M0mcikaJ
- 615 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 00:54:44 ]
- 何かエラー出るな。
ttp://codepad.org/M0mcikaJ
- 616 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 01:02:39 ]
- #define TEST "5" じゃダメなん?
- 617 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 01:07:15 ]
- >>616
まったくダメなことはないけど、質問がよく解らんから普段使わない機能を使ってみた。。。vv
- 618 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 01:22:07 ]
- >>591
dateの戻り値をdeleteされる場合を考慮しはじめると、何をどうチェックしたところで無駄。 どうにもならない。
- 619 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 01:24:05 ]
- >>599
二重deleteを防ぎたいなら「deleteしたらNULL入れる」なんてせずに、 auto_ptr/vectorをはじめとするRAIIスタイルのライブラリを使ったほうがいい。 無駄なNULL代入が減る分、効率も向上する可能性が高い。
- 620 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 01:29:02 ]
- ご返答ありがとうございます。
試してみたけど駄目でした… やりたいことは、 #define TEST 5 … char * a = { "TEST" }; この変数aがどうやってもTESTという文字列でしか認識されず、5が出せないのです。 char型の配列にはヌル文字が付くからマクロとして認識されてないのでしょうか…?
- 621 名前:620 mailto:sage [2010/02/19(金) 01:37:42 ]
- 型がLPCTSTRの所で変数aを入れてるのが原因かなぁ
- 622 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 01:37:50 ]
- なんか>>616でいいような気がするが。。。
文字列を結合したいならそういう関数を使う。sprintfとか
- 623 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 01:39:05 ]
- 情報の後出しは基本的にご法度だぜ。。。
ウインドウズ使っていいなら簡単な方法がある。ちょとコード書く。
- 624 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 01:39:47 ]
- む、LPCTSTR・・・・・とかhoge_sとか・・・
この辺の話はどうにかならんのかね・・・?
- 625 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:00:42 ]
- >>620
文字列リテラルの中はマクロ展 されない。
- 626 名前:620 mailto:sage [2010/02/19(金) 02:01:49 ]
- char型の配列使わずにint型の配列にTESTを入れて処理を進められました('A`)
大変ありがとうございました
- 627 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:05:03 ]
- #define TEST "5"
… char * a = { TEST }; これでいいんでないの?
- 628 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:05:12 ]
- お前それで良いのか
- 629 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:06:09 ]
- おっと>>628は>>626向け
- 630 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:06:37 ]
- >>586 codepad.org/eoOEH0RH
- 631 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:11:36 ]
- >>620
#include "boost/preprocessor/stringize.hpp" #define TEST 5 char const* a = BOOST_PP_STRINGIZE(TEST);
- 632 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:13:03 ]
- 手を抜くつもりが黒魔術になってしまった。
後悔はしてるが反省はしていない。 #include <stdio.h> #include <locale.h> #include <tchar.h> #include <windows.h> #define TEST 5 #define BufSize 1024 int main(){ TCHAR BUF[BufSize]; _tsetlocale(LC_ALL, TEXT("Japanese")); /*wsprintf(BUF,TEXT("ほげほげ戦隊 ほげほげ%d"),TEST);*/ _sntprintf_s(BUF,BufSize,TEXT("ほげほげファイブ「%d」"),TEST); _tprintf(TEXT("%s"),BUF); return 0; }
- 633 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:23:19 ]
- >>610
なんかうちの環境が悪いだけでしたあざす
- 634 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:29:21 ]
- >>630
これってstaticにする意味って何? あおりじゃなくてただの素人です
- 635 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:30:09 ]
- 俺は文字列リテラル外すマクロが欲しい
- 636 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:35:19 ]
- >>635
文字コードすべて暗記してint型の配列を確保してエンディアン考慮して 文字を16進数にでもして並べていけばリテラルいらないよ
- 637 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:40:11 ]
- >>634
static にしないと引数として this ポインタが付く。無駄な引数は付けないのが当たり前。
- 638 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:44:40 ]
- リテラル嫌なら
int a[2] = { 0x65676f68,0x00000000 }; printf("%s\n",(char*)&a[0]);
- 639 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:52:21 ]
- >>638
で、そう書く利点は?
- 640 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:53:55 ]
- 無いよ
リテラルがいやとかぬかすから書いただけ わざわざこんなめんどくさい書き方しなくてもいいようにC言語なりに考えられてるのに いやとかぬかすからねえ
- 641 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 02:56:11 ]
- 表示サンプルがhogeだったからまずかったのかね?
- 642 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 03:05:36 ]
- >>637
private な static メンバ関数ってそういう目的があるんすね ありがとうございます
- 643 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 03:07:01 ]
- 文字列リテラルを勝手に外部化して後付けで差し替え可能なリソースを作ってくれるプリプロセッサを所望してるんだよな
- 644 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 03:10:34 ]
- >>643
いいたいことがイマイチよくわからんがエスパー的ひらめきだと VC++のメニュー関連のリソースが浮かんだ しかも手書きでやらないといけないというのを・・・
- 645 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 03:12:21 ]
- >>640
誰も嫌とはいってなくね?
- 646 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 03:13:55 ]
- おまけにVCのリソースを標準関数に喰わせようとすると無茶苦茶大変だし。
- 647 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 03:15:07 ]
- vsくらいになるとsettingとかあるんだけどな
勝手にxml読み込んだり書き出したりしてくれる機能があってそこへ 文字とかいれておけば呼び出せたりするんだが
- 648 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 03:24:32 ]
- 文字列リテラル外部化って今でもできるんじゃね?
文字列リテラルだけ書き込みヘッダ用意してそこへ入れておけば・・・ そういうのとは違うのか?
- 649 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 07:23:21 ]
- >>613
解決しちゃったの? こういう話だと思ったんだけど。 #include <stdio.h> #define TEST 5 #define TO_STRING2(s) #s #define TO_STRING(s) TO_STRING2(s) int main() { const char *p = TO_STRING(TEST); puts(p); }
- 650 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 07:29:54 ]
- メモリの大きさがそれほど無い組み込み環境化だとC++って使われるんだろうか
std::stringとかの動作を考えてみてもすげー細かいレベルでメモリが断片化しそうなんだが
- 651 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 07:35:09 ]
- >環境化
環境下
- 652 名前:デフォルトの名無しさん mailto:sage [2010/02/19(金) 08:21:59 ]
- >>650
相応にメモリの使用量や動的確保のタイミングに注意を払えばいいだけのこと。 C++ はそういう環境でも使えるようにできている。
- 653 名前:620 mailto:sage [2010/02/19(金) 12:18:39 ]
- >>625
>>627 >>631 >>632 >>649 マクロ展開できてなかったのですか… 632と649にある方法を試したところ、ちゃんとマクロとして認識され、5が表示できました。 boost入れてなかったんで631にある方法は試せなかったのですが、boostを利用する方法もあったんですね。 今後も似たような場面に出くわす可能性が高いので、提示されたサンプルはメモらせてもらいます。 ありがとうございました。
|

|