C++相談室 part85
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2010/10/09(土) 20:22:35ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。
前スレ
C++相談室 part84
http://hibari.2ch.net/test/read.cgi/tech/1284736187/
0685デフォルトの名無しさん
2010/10/30(土) 00:55:08いやどういうときに使うものなのか見当がつかないだけだよ
0687デフォルトの名無しさん
2010/10/30(土) 00:56:29FILE*だもんな・・・
0688デフォルトの名無しさん
2010/10/30(土) 00:59:21ゴメン
やっぱboost::ptr_vector駄目だわ
これresizeするとポインタを通してデストラクタを呼ぶためのコンテナなんだよね
だからこの場合は駄目だと思う
0689デフォルトの名無しさん
2010/10/30(土) 01:33:47要するにこういう感じで勝手にデストラクタが呼ばれるといけないわけだよね?
#include <iostream>
#include <boost/ptr_container/ptr_vector.hpp>
class Test {
int i;
public:
Test(int j) : i(j) {}
~Test() { std::cout << "~Test(" << i << ") is called" << std::endl; }
};
int main()
{
boost::ptr_vector<Test> ptt;
for (int i = 0; i < 10; i++)
ptt.push_back(new Test(i));
boost::ptr_vector<Test>().swap(ptt);
std::cout << "Excecution done" << std::endl;
}
~Test(0) is called
~Test(1) is called
~Test(2) is called
~Test(3) is called
~Test(4) is called
~Test(5) is called
~Test(6) is called
~Test(7) is called
~Test(8) is called
~Test(9) is called
Excecution done
0690デフォルトの名無しさん
2010/10/30(土) 01:35:14vector を参照かポインタで扱っても、もともとの問題である vector に CFile を入れる段階の
問題が何も解決しない。
配列のコピーが行われたところで十分な空間・計算リソースがあれば問題にならないんで、
誰もが通る問題とも思えない。
0691デフォルトの名無しさん
2010/10/30(土) 01:36:14何も問題ないように見えるが、何がダメだって言うの?
0692685
2010/10/30(土) 01:43:44ちょくちょく出し入れしないとsharedする意味がないし、vectorにそれが向いてるとは思えない。
コンテナに入れる用途だとselectポーリングするとか、サーバー側のソケット/パイプ管理や
クライアント側のコネクションプールのようなものとかだけど、ポーリング以外では切断する役割
よりも使用未使用管理になると思うし、ポーリングを使うような状況でvectorは俺なら使わない。
そもそも面倒なのでポーリングしないで一個ずつスレッド使っちゃうし。
誰かvector<shared_ptr<CFile>>の利用用途を教えてくれー。
0693デフォルトの名無しさん
2010/10/30(土) 01:50:02いやいやだからpush_backしていくうちにメモリの再配置が起きてその時に
勝手にデストラクタが呼ばれてファイルストリームがクローズしちゃうじゃん
それを嫌がってるんでしょ?
自分でデストラクタを呼び出すならstd::vector<CFile*>でも何の問題もないような気がするんだけど
0694デフォルトの名無しさん
2010/10/30(土) 01:51:56shared_ptr が使われてるのは、単に C++2003 にはムーブや unique_ptr が無いからでしょ。
出し入れがしたいわけじゃないと思うよ。
「〜ような状況でvectorは俺なら使わない」と言うけど、それこそ理由が不明。
単に CFile の配列が欲しくて、実行時にしか要素数が決まらないってだけで十分でしょ。
0695デフォルトの名無しさん
2010/10/30(土) 01:56:02素人考えだとならlistではダメなの?って思うのですよ
利用用途が思いつかないからいいのかどうか見当もつかないんですけど
0696デフォルトの名無しさん
2010/10/30(土) 01:56:40単にoperator[]を使いたいんだと思うよ
0697675
2010/10/30(土) 01:59:35>いやいやだからpush_backしていくうちにメモリの再配置が起きてその時に
>勝手にデストラクタが呼ばれてファイルストリームがクローズしちゃうじゃん
まさにこれです。
vector<CFile> files;
files.resize(1);
files.resize(2); // ←ここでメモリの再配置がおきて、files[0] のデストラクタでファイルが閉じられるので困る
CFile の配列を使うことはあまりないかもしれませんが、
可変個のウィンドウを扱う(HWND)、ビットマップを扱う(HBITMAP)、などはよくあると思います。
>>692 で1個ずつスレッドにしても、スレッドを管理する HANDLE を持つクラスの可変長配列が必要です。
0698デフォルトの名無しさん
2010/10/30(土) 02:00:40何のための ptr_vector だよ。
ptr_vector なら再確保が発生してもポインタのコピーだけすればよくて、
オブジェクト本体のコピーが要らない。したがってデストラクタが呼ばれたりもしない。
自分でデストラクタを呼び出すなんて、論外だね。
0699デフォルトの名無しさん
2010/10/30(土) 02:06:140700デフォルトの名無しさん
2010/10/30(土) 02:07:290701デフォルトの名無しさん
2010/10/30(土) 02:10:21それはわかってる
でも今回のように勝手にデストラクタが呼ばれては困るファイルストリームインスタンスへの
ポインタを保持する場合は駄目でしょって
0702デフォルトの名無しさん
2010/10/30(土) 02:12:460703デフォルトの名無しさん
2010/10/30(土) 02:16:31なるほどまづは前提として受け入れろと
>>697
なるほど。リソースハンドル全般の話で使いまわしとは関係がない話なのですね。
オブジェクトとリソースの生成/消滅は原則連動してて、未参照状態で自動的に
消滅さ&コンテナはとにかくvectorがいいと。
0xはまだまだ知らないことだらけだけど、なんか面白そうですね。
0704デフォルトの名無しさん
2010/10/30(土) 02:21:19>>689にこれじゃ駄目でしょうって例をわざわざ貼り付けたんだけど理解できないかな?
0705デフォルトの名無しさん
2010/10/30(土) 02:31:12テンポラリに swap() で内容を移してるんだから、そのテンポラリの消滅で
デストラクタが走って当然。これを「勝手に」とか言ってるのがどういうことなのか
理解できない。
0706デフォルトの名無しさん
2010/10/30(土) 02:37:08いやだから・・・std::vectorでpush_backして行くとそのうち連続したエリアが足りなく
なってメモリの再配置が起きるでしょうって
boost::ptr_vectorも事情は同じですよって言う意味で書いたんだけど分かってもらえないかな?
0707デフォルトの名無しさん
2010/10/30(土) 02:46:410708デフォルトの名無しさん
2010/10/30(土) 02:48:16外行って頭に水ぶっかけて来い
0709デフォルトの名無しさん
2010/10/30(土) 02:50:18http://ideone.com/C0UYF
capacity() == size()はcapacity()が満たされた場合であり、再配置が起こる
明示的にresize()も呼び出してみた
再配置が起こってもデストラクタは起動しない
スコープアウトしてはじめてデストラクタが起動する
0710デフォルトの名無しさん
2010/10/30(土) 02:52:21おっと。似たようなことしてる人が・・・
0711デフォルトの名無しさん
2010/10/30(土) 02:53:380712デフォルトの名無しさん
2010/10/30(土) 03:00:010713デフォルトの名無しさん
2010/10/30(土) 03:04:270714デフォルトの名無しさん
2010/10/30(土) 03:05:560715デフォルトの名無しさん
2010/10/30(土) 03:18:200716デフォルトの名無しさん
2010/10/30(土) 03:19:55・但しイテレータは無効になる
か
0717デフォルトの名無しさん
2010/10/30(土) 03:28:21あくまでポインタを保持している場合の話な
>>709のコード貼っといて言うのもアレだが
オレはコンテナにファイル管理クラスを突っ込んだりしないけどな
入れるとしたらファイル名とかリソースバッファか
ファイル処理なんてエラーが出やすいし、アクセスは単純化してわかりやすい方がいい
こんな論争現場でしたくないだろw
0718デフォルトの名無しさん
2010/10/30(土) 03:31:420719デフォルトの名無しさん
2010/10/30(土) 09:58:53CFileってコピー可なのか?普通はコピー不可にするべきだろう。MFCって一体?
コピー不可でも、C++0xならムーブ可にしておけばvectorに入るだろうし、突然閉じたりしないしな
0720デフォルトの名無しさん
2010/10/30(土) 10:39:12それにMFCのCFileはコピー不可だよ
0721デフォルトの名無しさん
2010/10/30(土) 13:15:33list じゃだめなん?
HWND なんか典型的にリストの出番だと思うし
それ以前に EnumWindows だろ
vector に push_back を多用する時点で何かおかしいと思わないのか?
resize で不具合が出るのをわかっていて resize にこだわる時点で何かおかしいと思わないのか?
ちなみに MFC は RTTI や文字列を自前で作っているが、それがどういう意味かわかる?
0722デフォルトの名無しさん
2010/10/30(土) 13:51:21// ・・・・
set<int>::iterator it = s.begin(), end = s.end();
while(it != end)
{
DoSometing(s, *it);
++it;
}
DoSometingでコンテナの要素が増減する可能性がある場合ってイテレーターは無効になりますか?
0723デフォルトの名無しさん
2010/10/30(土) 13:57:450724デフォルトの名無しさん
2010/10/30(土) 14:56:48itがさしている要素が削除されるとitが無効になるよ。
0725デフォルトの名無しさん
2010/10/30(土) 15:08:37/ \ /\ キリッ
. / (ー) (ー)\
/ ⌒(__人__)⌒ \ <HWND なんか典型的にリストの出番だと思うし
| |r┬-| | それ以前に EnumWindows だろ
\ `ー'´ /
____
/ \ /\ キリッ
. +/ (●) (●)\
/ ⌒(__人__)⌒ \+
| | クスクス>
\ /
____
<クスクス / \ /\ キリッ
. / (●) (●)\
/ ⌒(__人__)⌒ \ +
| |
+ \ /
0726デフォルトの名無しさん
2010/10/30(土) 15:15:110727デフォルトの名無しさん
2010/10/30(土) 15:18:310728デフォルトの名無しさん
2010/10/30(土) 15:21:590729デフォルトの名無しさん
2010/10/30(土) 15:24:33ダメプログラマーになりたいのなら別だがな
0730デフォルトの名無しさん
2010/10/30(土) 15:24:450731デフォルトの名無しさん
2010/10/30(土) 15:25:290732デフォルトの名無しさん
2010/10/30(土) 15:27:06ダメプログラマーになりたいのなら別だがな
0733デフォルトの名無しさん
2010/10/30(土) 15:28:450734デフォルトの名無しさん
2010/10/30(土) 15:33:390735デフォルトの名無しさん
2010/10/30(土) 15:35:380736デフォルトの名無しさん
2010/10/30(土) 15:37:310737デフォルトの名無しさん
2010/10/30(土) 15:42:00そういえばこれのコールバックをコルーチンでiterateする面白い実装をどっかで見たな
0738デフォルトの名無しさん
2010/10/30(土) 15:44:21空笑がみられる病人がいるようだが
許したければ許せばいいだろ自分で
0739デフォルトの名無しさん
2010/10/30(土) 15:54:400740デフォルトの名無しさん
2010/10/30(土) 15:56:22自分に言ってるのか
0741デフォルトの名無しさん
2010/10/30(土) 16:02:26いや、素直な感想を言ってるだけ
0742デフォルトの名無しさん
2010/10/30(土) 16:04:310743デフォルトの名無しさん
2010/10/30(土) 16:15:390744デフォルトの名無しさん
2010/10/30(土) 16:18:57意味のない一言煽り多いよな。それしかできなそうって感じもするけど。
0745デフォルトの名無しさん
2010/10/30(土) 16:43:140746デフォルトの名無しさん
2010/10/30(土) 17:08:210747デフォルトの名無しさん
2010/10/30(土) 17:12:29vectorでは禁じ手
というかメンバ関数がなかったんじゃないか?
0748デフォルトの名無しさん
2010/10/30(土) 17:17:100749デフォルトの名無しさん
2010/10/30(土) 17:18:12というかメンバ関数がなかったんじゃないか?(キリッ
0750デフォルトの名無しさん
2010/10/30(土) 17:22:15許してやれよw
0751デフォルトの名無しさん
2010/10/30(土) 17:26:10vectorの速度的な話で大規模な配列を取り扱う場合
遅い順に
reserveされてない領域へのpush_back
reserveされてる領域へのpush_back
resize等で既に確保されてる領域への代入
vectorを使わない静的配列への代入
って感じであってる?
push_backが遅いのは仕様だよね?
0752デフォルトの名無しさん
2010/10/30(土) 17:31:31vectorを使わない静的配列への代入
これは同じじゃないかな
0753デフォルトの名無しさん
2010/10/30(土) 17:42:17そうなのかな?
適当に10個ほどの変数をもつ構造体で
静的の方は各変数ごとに代入
vectorの方は各変数ごとに代入とoperator=による代入両方で計測してみたんだけど
どうも静的のほうが微妙に速いんだ
誤差の範囲といえばそうなんだが計測に仕方が悪いのかな
0754デフォルトの名無しさん
2010/10/30(土) 17:52:21例えされたとしても複雑なアドレス計算が絡みそうなので単純な配列に比べたら
可哀想だ
でもEfficient C++を読むと分かると思うけど、vectorは本当に速いよ
0755デフォルトの名無しさん
2010/10/30(土) 18:10:250756デフォルトの名無しさん
2010/10/30(土) 18:15:25vector<Hoge, Ator> va;
v = va;
swap(v, va);
//etc.
これサポートされてないんだけどなんかイカす回避手段はありますか?
0757デフォルトの名無しさん
2010/10/30(土) 18:23:160758デフォルトの名無しさん
2010/10/30(土) 19:21:20> reserveされてる領域へのpush_back
> resize等で既に確保されてる領域への代入
これは前者がコピーコンストラクタ、後者が代入演算子を使うことになるから、
既存の要素の取り扱いを考慮する分で、一般的には後者のほうが遅いだろう。
コピーをユーザー定義したクラスの実装によっては逆転することもあるだろうけど。
0759デフォルトの名無しさん
2010/10/30(土) 19:54:160760デフォルトの名無しさん
2010/10/30(土) 23:07:030761デフォルトの名無しさん
2010/10/30(土) 23:17:31shared_ptrが指しているインスタンスが一つも指されなくなったら
つまりこれはお互いに指し合うと永久にdeleteされなくなるので
一個だけweak_ptrを挟む
0762デフォルトの名無しさん
2010/10/30(土) 23:19:27ここが良くまとまっている
0763デフォルトの名無しさん
2010/10/30(土) 23:33:05関東人乙
俺関西人やけど、pop_front使うときはdequeでそれ以外はvectorって決めてるわw
0765デフォルトの名無しさん
2010/10/30(土) 23:40:330767デフォルトの名無しさん
2010/10/31(日) 00:50:46> >>761-762
> thx
> どうやって参照カウントが0になったことをshared_ptrは知るんですか?
0768767
2010/10/31(日) 00:51:51ごめんよ
0769デフォルトの名無しさん
2010/10/31(日) 01:06:04libxml2とapache xercesって使いやすいですか?
0770デフォルトの名無しさん
2010/10/31(日) 11:52:29http://users.rcn.com/jcoplien/Patterns/C++Idioms/EuroPLoP98.html#PromoteAndAdd
上記のウェブサイトのソースコードでconst参照仮引数に代入しているように
みえるのですが良くわかりません。
ちなみにisA関数の意味もcomplexExemplarの意味もわかりません。
教えてください。
0771デフォルトの名無しさん
2010/10/31(日) 15:15:29XML自体が使いにくい。どっちでも特に使いにくいとか使いやすいとか思わなかった。
>>770
細かいことは気にするな。コードはかなり適当っぽい。
0772デフォルトの名無しさん
2010/10/31(日) 15:25:29例えば、関数形式のマクロに別のマクロを引数として与えたとき、引数の方が先に処理される
ようなことはないみたいですけど、単に記述順に処理されるんでしょうか。
0773デフォルトの名無しさん
2010/10/31(日) 15:42:540775デフォルトの名無しさん
2010/10/31(日) 16:05:500776デフォルトの名無しさん
2010/10/31(日) 16:45:510777デフォルトの名無しさん
2010/10/31(日) 17:32:080778デフォルトの名無しさん
2010/10/31(日) 17:37:39こんな宣言をすることができるらしいのですが、
コンパイラが禁止しているからエラーがでるのですか?
また、この時の型は何になるんですか
0779デフォルトの名無しさん
2010/10/31(日) 17:40:57auto_ptr はテンポラリからのコピーができないので、その初期化形式(コピー初期化)では
コンパイルエラーになる。
... c(new Class) とすれば(形式を直接初期化にすれば)コンパイルできる。
型は書いたとおりの std::auto_ptr<Class> 。
0780デフォルトの名無しさん
2010/10/31(日) 17:56:10explicit を学べ
0781デフォルトの名無しさん
2010/10/31(日) 17:58:030783デフォルトの名無しさん
2010/10/31(日) 18:14:42基本的に記述順に処理される
詳しくは
http://www.spinellis.gr/blog/20060626/
このあたりで
>>781
explicitがなければT *からの変換コンストラクタが定義できてしまうのでは?
0784779
2010/10/31(日) 18:19:39ごめん。間違ってた。
auto_ptr も auto_ptr_ref 経由でテンポラリから初期化ができる。
>>778 のコードでテンポラリを使った初期化にならないのは
auto_ptr<T>::auto_ptr(T*) に explicit が付いているから。
直接初期化の形にすれば当然 expliciti の制限は受けず、
auto_ptr<T>::auto_ptr(T*) が使用される。
■ このスレッドは過去ログ倉庫に格納されています