1 名前:デフォルトの名無しさん mailto:sage [2014/03/25(火) 00:45:54.57 ID:VoemgV7u] エスケープシーケンスやWin32APIなどの環境依存なものでもOK。 ただしその場合、質問者は必ず環境を書きましょう。 ※sage禁止です(と代々スレに書いてありますが自己判断で)。 【前スレ】 【初心者歓迎】C/C++室 Ver.89【環境依存OK】 toro.2ch.net/test/read.cgi/tech/1390171944/ ◆ソースのインデントについて 半角空白やTABでのインデントはスレに貼ると無くなります。 そのため、アップローダーに上げるのも手ですが直接貼る場合は、 全角空白か に置換すると見栄えだけはよくなります。 【アップローダー】(質問が長い時はココ使うと便利) codepad.org/ (コンパイルもできるし出力結果も得られる[]privateをチェック) ideone.com/ (時間帯によってはcodepadが重い事があるのでここも利用) hogeは禁止します、使用しないでください。 万が一hogeが書き込まれても、スルーしてください。 相手にするとあなたも荒らしと同じ扱いになります。 なお、hogeはNGワードに追加しておくことが強く推奨されています。
263 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 20:02:57.67 ID:g31zNjzu] >>262 read(2) の manには EISDIR fd refers to a directory. Other errors may occur, depending on the object connected to fd. POSIX allows a read() that is interrupted after reading some data to return -1 (with errno set to EINTR) or to return the number of bytes とある
264 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 20:41:55.55 ID:DVvt3Ia1] 最近C++勉強始めたんですが、質問があります。(Cは良く分っているつもりです)。 C++には参照渡しという記述方法があることを知ったのですが、Cのポインタ渡しに 慣れている私としては、参照渡しを使わずにすべてポインタ渡しでコードを記述する ほうが見易いので、そうしようかと思うのですが、何かデメリットありますか? 参照渡しを使うほうがよい点などありましたら教えてください。
265 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 20:51:36.33 ID:UPYb5gKr] (個人的に思う)一般的に ポインタで渡す=ヌルが渡ってくる可能性がある、つまり、常にヌルチェックが必要 ポインタで渡す=ヌルが渡せる、この引数はオプション的である 参照で渡す=なんかしらわたってくる、ヌルチェック不要 参照で渡す=この引数は必ず必要である あと一時変数オブジェクトの寿命の関係とかあった気がするが忘れたw
266 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 21:14:47.05 ID:iMQET/ga] >>264 ポインタ渡しと違い、参照渡しの場合、 ・絶対に実体があるので、適当なアドレスが渡って 不正なメモリアクセスを行うことがない また、参照する中身は変更できないので紛れがない ・普通の変数と同じように記述できる。構造体のメンバ関数にも アロー演算子ではなくドット演算子でアクセスできる また、関数の引数に使った際、呼び出す側としてはいちいち アドレスを渡すということを意識せず使用できる ・ポインタと違い参照自体にはメモリ消費がない こんなところか
267 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 21:17:29.88 ID:lcY87dee] 返り値の話ではないとして。 参照渡しの一番のメリットは渡したオブジェクトの所有権が移動しない事がわかる事かな。
268 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 21:21:57.27 ID:lEZQ3TFl] メモリ消費がないというのは不適切だろ インラインで消えたりするが
269 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 21:46:00.21 ID:iMQET/ga] >>268 いや、俺の持ってる本では 「ポインタと違って独自にメモリ領域が割り当てられない」 的なことが書いてあるんだが……違うの?
270 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 21:49:58.13 ID:7APDnn3f] (お前が)(malloc/new等で)と読めなくもないが大丈夫か
271 名前:デフォルトの名無しさん [2014/04/14(月) 21:55:35.64 ID:buURFUek] 初期のC++はC言語へのコンバータで実現してたろ。 参照も内部的にはポインタ動作と変わらないかと。
272 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 22:00:06.15 ID:iMQET/ga] >>271 それって「参照がポインタで実装されてる(ことが多い)」って話じゃなかった?
273 名前:264 mailto:sage [2014/04/14(月) 22:02:44.39 ID:DVvt3Ia1] みなさん解説ありがとうございます。 大変参考になります。 >参照渡しの一番のメリットは渡したオブジェクトの所有権が移動しない事がわかる事かな。 もう少し詳しく解説お願いします。
274 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 22:04:37.96 ID:iMQET/ga] あとこんなページも見つけた detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1320144958 www.osak.jp/program/arg_ref_val.html
275 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 22:18:22.93 ID:msrdBAHC] >>269 通常の実装では、呼び出し側ではスタックにアドレスを積むという点で全く同じだし、 呼ばれる側でもそこを参照するのに違いはないよ。 まぁ、インライン展開で消えれば話は別だけど。 一番のメリットは、(参照先ではなく)参照自体を書きかえられないことだね。 それもまた、ポインタでもconstにすればできるわけだけど。
276 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 22:54:29.26 ID:CAt5QB21] ttp://codepad.org/Qo0ErNs1 この例ではポインタで渡す気が起きない
277 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 23:06:35.99 ID:lcY87dee] >>276 const付けような。
278 名前:264 mailto:sage [2014/04/14(月) 23:14:28.51 ID:DVvt3Ia1] >276 サンプルコードありがとうございます。 >この例ではポインタで渡す気が起きない すみません、まだよく分らないのですが、ポインタで void WriteLine(const string *pstr) { printf("%s\n", pstr->c_str()); } のようにすると何か問題があるのでしょうか?
279 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 23:17:14.74 ID:lcY87dee] codepad.org/UUMHZZxJ 参照にするとこうかける
280 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 23:20:11.44 ID:i+D5B13r] >>273 ++や--の挙動がポインタと参照で違うんじゃね?
281 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 23:32:46.57 ID:lcY87dee] >>273 ポインタでオブジェクト返されると誰がdeleteすべきなのかドキュメント見るか返す関数の中身見るまでわからないよね? 参照にすると返したやつが所有している物の中身を見させて貰ってるってことがわかるからdeleteしなくていいって事がドキュメント見なくてもわかる。 引数でもポインタだと引数で渡されたポインタを内部で保持しておくから呼び出し側でdeleteや中身の変更をしてはだめになるのかとかわからない。
282 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 23:41:59.74 ID:CAt5QB21] >>278 ttp://codepad.org/uAzCCBJQ ポインタでも書けるしこの例では問題はない が、やっぱり人に見せると「何で参照使わないの?」と言われそう
283 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 23:54:52.78 ID:73GA0vhp] string *str = new string("hello"); .... delte str; .... WriteLine(str); //deleteしてるけど、、、ポインタ値は生きてるから アッー 結局、コンテナをうまく使って生ポ(生new)は極力排除しようぜって流れ
284 名前:デフォルトの名無しさん mailto:sage [2014/04/14(月) 23:59:10.65 ID:lcY87dee] >>282 なんで「何で参照使わないの?」と言われるのかその理由を書かないと意味ないだろ。 たとえば codepad.org/wCMxFlfO 文字列を返す関数と文字列を引数にとる関数があるとする。 参照だったら文字列を返す関数を文字列を引数にとる関数の引数に直接書ける ポインタだったら一度ローカル変数で受け取ってそのポインタを書かないとだめ
285 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 00:13:55.46 ID:MOmoi8a1] int& a = *(int*)0; a = 0;
286 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 00:17:57.06 ID:lShoPitp] ポインター操作が目的でなく null許可を表現させたいわけでもなく 読み取り用途限定の時に わざわざポインターを使う方が不自然
287 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 00:21:36.20 ID:jMxUSFKT] >>285 一行目がダメコードって一目瞭然じゃないか。 ポインタだったらnullを渡すのが悪いのか?nullチェックせずに代入するほうが悪いのか?になる >>286 ポインタしかない世界から来た人には多分通じないよ。
288 名前:デフォルトの名無しさん [2014/04/15(火) 00:25:16.54 ID:hh7KqCRP] 生ポ引数/戻り値なんて特別理由がある場合以外は使うなってこった
289 名前:264 mailto:sage [2014/04/15(火) 00:28:56.87 ID:7FIahpja] 私なりに結論を出してみたのですが、 参照渡しをするのは、 void WriteLine(const string &str); みたいに、その関数に値を読み取り限定で渡す場合に主に使う。 ただし、必ずconstを付けておく。 上記以外はポインタ渡しを使う。 で良いでしょうか?
290 名前:デフォルトの名無しさん [2014/04/15(火) 00:35:43.12 ID:8L+RgIaL] 参照はポインタの初心者版みたいなもの。 使い方が分からないのがあえて使わなくていい。
291 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 00:36:31.44 ID:c0zlhsuS] >上記以外はポインタ渡しを使う いいえ。 その他にもムーブセマンティクスを達成 したいときにも参照を使います。
292 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 00:45:18.87 ID:jMxUSFKT] >>290 っていうC++初心者が書くコードはひどく読みづらいので真に受けたらだめ
293 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 01:27:44.04 ID:PjplhgrG] ageる奴は碌なこと喋んねーな
294 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 03:06:53.30 ID:2JpOUwgl] >>289 漏れも俺様ルールで、const参照は読み取り用、 ポインタは値を変更する時と、使い分けている
295 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 06:05:04.19 ID:sGkhMKKa] >>289 ttp://ideone.com/SIOYc5 なかなかいい例が思い浮かばないが この例ではconstを付けられないが参照が相応しいと思う 全てに当てはまる使い分けの条件は提示できないので 個人やチームの判断で使い分けするしか
296 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 07:52:53.60 ID:AA0ZYDWw] 格納場所という意味で>289が作った関数仕様を実装する場合も、自衛はするべき。 void readSome(Type * const result) { // ++result; // これがエラーになってくれる。 }
297 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 08:09:35.12 ID:6lm4j3zL] 俺はしないな。 意味的にはそうなのだけれど C++のconstは真面目に付けると可読性を著しく損なう
298 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 08:59:58.71 ID:Byz6doxp] >>263 うん。262は間違いでした。 調べたらreaddirはgetdents(2)を呼んでた そりゃそうか。ファイルシステムで構造違うしな
299 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 10:42:12.48 ID:ZiuccpsX] >>296 そのレベルは冗長
300 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 12:47:22.14 ID:tCJ2yelK] 参照なら要らないのにね。
301 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 12:54:41.51 ID:dDf7e/l1] 値渡しの引数にconstをつけるのはやりすぎな気がする void f(const int x) なんてしないでしょ
302 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 13:09:58.76 ID:tCJ2yelK] する奴いるよ。きっと>296も同じタイプ。
303 名前:KAC mailto:sage [2014/04/15(火) 13:26:56.79 ID:OYr23JgA] >>296 なんか違う事書いてるぞ。>289の仕様満たすならconstは*の左。 >>297 どんな所で可読性が落ちるって? お前がまともに使えないだけじゃないの?
304 名前:デフォルトの名無しさん [2014/04/15(火) 14:19:33.38 ID:SFbbbO6x] 流れぶった切って悪いんですが >>251 の c_myclassがインターフェースクラスを継承している場合は 継承元メンバ(インターフェースクラス)に仮想デストラクタを書いておけば良いのですか?
305 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 14:41:39.21 ID:tCJ2yelK] >>303 >296が言いたいことは、>289の仕様ならconst * string const strだろ。
306 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 14:42:44.92 ID:tCJ2yelK] いけね、Typo。 string const * const strね。
307 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 14:59:38.52 ID:JmWJ8ekL] >>304 違いが分かればよいのだが… ideone.com/w9UqT0
308 名前:デフォルトの名無しさん [2014/04/15(火) 15:09:29.49 ID:SFbbbO6x] >>307 さらっと確認したので怪しいのですがたぶん クラスAには仮想デストラクタが無い為に newしたオブジェクトがデリートされる際、継承元のデストラクタが呼び出されていませんが、 クラスBは仮想デストラクタがメンバにあるので deleteされる際に継承元のデストラクタが呼び出される訳ですよね そこで、ベクターにオブジェクトを格納する話につながる訳ですが >>251 のc_myclassがインターフェースクラスを継承しているときには やはり継承元のクラスに仮想デストラクタを記述しておかないと危険だという事ですよね?
309 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 15:27:23.32 ID:JmWJ8ekL] だーね
310 名前:デフォルトの名無しさん [2014/04/15(火) 15:32:30.40 ID:SFbbbO6x] 確認しつこくてすいませんが まとめると>>307 のdlvBを dlvB temp std::vector<dlvB> obj; obj.push_back(temp); みたいにしちゃっておkってことですよね
311 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 18:05:27.38 ID:ef3kTbvB] >>310 そうしたいなら仮想デストラクタとか仮想関数とか関係ない。 コピーコンストラクタを作ればいいだけ。
312 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 18:37:17.89 ID:u428dFct] std::vector<clsB>にdlvB型のオブジェクトを突っ込むとスライシングでダメになるから気をつけるように 多態をコンテナ内で実現したいならstd::shared_ptrやunique_ptrを入れるのがよい
313 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 20:01:11.81 ID:Nbqron3B] 仮想デストラクタが必須なのは当然として vectorに突っ込むケースを考えると 難易度としては vetcor<Base> vetcor<Base*> vetcor<shared_ptr<Base>> ptr_vector<Base> こんな感じじゃね? それぞれ注意点はあるが 一見簡単そうに見える vetcor<Base> が一番きつい
314 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 20:12:18.40 ID:MU2KfTCa] >vetcor<Base> そもそも派生クラスを突っ込めない。 >vetcor<Base*> 所有権がどこにあるのか分からないので論外。 >vetcor<shared_ptr<Base>> virtualデストラクタ不要で便利。 >ptr_vector<Base> 今更ptr_vector?unique_ptrでいい。
315 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 20:33:50.00 ID:O7xBtcGx] make_uniqueが標準に入らないと、記述量がちょっと面倒
316 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 20:42:49.07 ID:Nbqron3B] >>314 たしかに デザパタで 知らんかった 流行り廃りとかあるの?デザパタで
317 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 20:49:25.61 ID:aOtL598m] std::unique_ptrはvectorに突っ込めるのにboost::scoped_ptrは出来ないのはなんで?
318 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 20:54:50.82 ID:tBkVUf7m] moveできないから
319 名前:デフォルトの名無しさん [2014/04/15(火) 23:53:29.68 ID:hh7KqCRP] noncopyableだからだろ
320 名前:デフォルトの名無しさん mailto:sage [2014/04/15(火) 23:56:04.64 ID:of9IS0B8] ユニポもそうだけど
321 名前:デフォルトの名無しさん [2014/04/16(水) 00:00:41.11 ID:cUKcFdx2] >>320 すまん、そうだね、copyかmoveが出来ないとコンテナには入れられないということで