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


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

C++相談室 part122



1 名前:デフォルトの名無しさん mailto:sage [2016/01/23(土) 23:06:15.32 ID:HdItgJjm.net]
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。

前スレ
C++相談室 part121
peace.2ch.net/test/read.cgi/tech/1449240881/


このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.97【環境依存OK】
peace.2ch.net/test/read.cgi/tech/1439849418/

次期規格C++1zはこちら
C++14/C++1z 20
peace.2ch.net/test/read.cgi/tech/1410382924/

■長いソースを貼るときはここへ。■
 codepad.org/
 ideone.com/

2 名前:デフォルトの名無しさん mailto:sage [2016/01/23(土) 23:07:25.42 ID:HdItgJjm.net]
[C++ FAQ]
https://isocpp.org/wiki/faq/
www.bohyoh.com/CandCPP/FAQ/ (日本語)

3 名前:デフォルトの名無しさん mailto:sage [2016/01/23(土) 23:11:46.68 ID:HdItgJjm.net]
STLつかうと一気に実行ファイルサイズが10倍に?!

環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない

すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。

C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?

#include <stdafx.h>
後死ね。

言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。

4 名前:デフォルトの名無しさん mailto:sage [2016/01/23(土) 23:14:12.22 ID:HdItgJjm.net]
---- テンプレ ここまで ----

5 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 02:28:04.57 ID:0LR1dPfv.net]
前スレ>>935でスマポ関連の質問をした者ですが、すみませんがもう一度質問させてください。
今の糞コードはこんな感じです。

class A {
 vector<shared_ptr<B>>; // 要素は数十個
};
class B {
 vector<shared_ptr<C1>>; // 要素は数万個、要素内の状態に応じてソート
 vector<shared_ptr<C2>>; // 同上
 vector<shared_ptr<C3>>; // 同上
 weak_ptr<A>;
};
class C1 {
 weak_ptr<A>;
 weak_ptr<B>;
};
class C2 {
 vector<weak_ptr<C1>>; // 要素は数十個
 weak_ptr<A>;
 weak_ptr<B>;
};
class C3 {
 vector<weak_ptr<C2>>; // 要素は数十個
 weak_ptr<A>;
 weak_ptr<B>;
};

クラスの階層としては A→B→C1,C2,C3 ですが、以下を満たした上での適切なクラス設計が分かりません。
・クラスの異層間および同層間の参照がある
・B内のvectorを要素の状態に応じてソートする

これらのスマポやコンテナをどう変えるのが適切なんでしょうか?

6 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 08:22:51.32 ID:TFTujVHZ.net]
どのタイミングでB,C1,C2,C3が作られるのかが分からないとコメントできない
最初に結合考えられてない状態で全部オブジェクトが作られてそのあとつながっていくパターンなのか、
それとも親が子を作るパターンしかありえないのかで話は変わる

あとクラスの階層って表現は基本的にクラスの派生・クラスの上位下位って意味で使われるから、そういう場合はノードの親子関係とかそういう言葉を使った方がいい

7 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 11:39:36.09 ID:LHp2Xjej.net]
AやB、C1、C2、C3がどういう意味を持つのか分からんとアドバイスは難しいかな。
もしかしたら全て同じクラスで表現して、有向グラフとして構成するのが一番かも知れん。

> クラスの異層間および同層間の参照がある
ノード間に自明な階層構造があるなら、親への弱いポインタとノードの参照パラメタのタプルを持てばいいんじゃない?
class A {
friend B;
vector<shared_ptr<B>> b;
};

class B {
weak_ptr<A> a;
size_t B_index;
}; // this == a.lock()->b[B_index].get();

> B内のvectorを要素の状態に応じてソートする
これはstd::sortで行ける。
尤も、ベクタが常にソートされた状態に保たれるって条件にしたいなら挿入ソートの方が計算量が少なくなって良いけどね。
ex)
sort(c1.begin(), c1.end(),
[](const shared_ptr<C1>& e1, const shared_ptr<C1>& e2) {
return compare(e1->get_parameter(), e2->get_parameter());
}
);

8 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 13:20:32.74 ID:6/siiwPN.net]
ファミコン世代なのでbelongs toって言い回しが怖くて使えない…

9 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 13:26:35.94 ID:efwl3LYy.net]
All your base are belong to us

10 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 14:29:49.80 ID:7wa58CB+.net]
>>8
何で?



11 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 16:17:33.38 ID:6/siiwPN.net]
>>10
All your base are belongs to us.
これ訳せる?

12 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 16:30:11.35 ID:7wa58CB+.net]
>>11
そんな英語を書いちゃうのが怖いってこと?
それとも英語圏だと有名な言い回しか何かってこと?

ごめん、文法詰め込み教育受けた典型的な日本人なんで、訳せないす…

13 名前:5 mailto:sage [2016/01/24(日) 16:51:59.34 ID:0LR1dPfv.net]
>>6
>最初に結合考えられてない状態で全部オブジェクトが作られてそのあとつながっていくパターンなのか、
最初は何も考えずそうしていました。つまり、全てのオブジェクトをshared_ptrで作っていました。
ただ、前スレの指摘からshared_ptrを意味もなく使うのは駄目だと悟ったので、
ノード間に自明な親子関係があることから、素直に「親が子を作る」ほうがいいかと思いました。

>>7
書き忘れましたが、全てのクラスはインデックスを表すメンバ int index を持っており
これに従ってvectorをソートしたいのでした。
こういう場合shared_ptrやweak_ptrを使うのは悪くないということでしょうか?

14 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 18:26:26.83 ID:LHp2Xjej.net]
>>13
最終的に何をやりたいかにもよる。

全てのノードへのポインタをunordered_setで保持して、確保するときは必ずそのunordered_setにinsertし、ノード間は生のポインタを使う
なんて実装も可能で、場合によってはその方が実行速度が速い。

BはA以外からは所有されないのであれば、shared_ptrよりunique_ptrの方が意味的には適切。

15 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 18:34:36.48 ID:fkWZRTEw.net]
>確保するときは必ずそのunordered_setにinsert

挿入が随分とマヌケなコードにならないか?

16 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 18:36:18.10 ID:fkWZRTEw.net]
あ、間違えた失礼

17 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 18:38:12.34 ID:LHp2Xjej.net]
関数なりマクロなりに隠すから問題ない
ホントの事いってunordered_setなんぞあんまり使ったこと無いんだけど、大体こんなイメージ

T* my_new(unordered_set<T*>& heap) {
auto t = new T;
heap.insert(t);
return t;
}

18 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 18:42:20.30 ID:50ZcCt7z.net]
>>5
そのコードで何か具体的な問題が起こってるのでもなければそれでいいんじゃないの?
問題があるならそこをはっきりさせないと、どう変えようかなんて考えようが無いと思う。
効率を気にしてるだけなら実測して要件を満たすならそれでいいし。
名無しの誰かの主観を満足させたいわけじゃないんでしょ?

19 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 19:33:35.42 ID:fkWZRTEw.net]
>>17
スマポをunordered_setに入れるものと勘違いして>>16で撤回した俺がアホだった
やはり初心者にはC++は難しかったようだ
ideone.com/NUiLph

20 名前:デフォルトの名無しさん mailto:sage [2016/01/24(日) 21:56:44.58 ID:ssnQMLKn.net]
>>12
有名な間違いだらけの英語



21 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 08:20:39.98 ID:8HrLEsp2.net]
>>19
そのunordered_setのvalueは生ポインタじゃなくて最初からスマートポインタでよくない?
あとインデックスあるんだからunordered_map使ったほうがすっきりしそう。まあここは質問者のやりたいこと次第だしそもそも>>14のsetの流れで出てきたものなんだろうけど

22 名前:デフォルトの名無しさん [2016/01/25(月) 10:55:34.57 ID:yh3tfuOH.net]
void hage()
{
struct hoge
{
char a;
int b;
};
hoge a;
memset( &a, 0, sizeof( hoge ) );
hoge b = {};
hoge c = hoge();
hoge d = { 0, 0 };
bool e = memcmp( &a, &b, sizeof( hoge ) ) == 0;
bool f = memcmp( &a, &c, sizeof( hoge ) ) == 0;
bool g = memcmp( &a, &d, sizeof( hoge ) ) == 0;

}
efgはそれぞれどういう値になるでしょうか

23 名前:5 mailto:sage [2016/01/25(月) 11:17:27.48 ID:2nNO2C2F.net]
>>18
問題は全くないです。
ただ、スマポを正しく使えてる自信がなかった中、前スレ>>956等を見てやばいと焦った次第です。

>>14
生ポインタ使うのは正直抵抗があるので今回は見送ります。
unique_ptrは仰る通り使うべきでした。

24 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 11:21:09.85 ID:aGf3VXDj.net]
>>22
規格で保証がある範囲を考えれば全部不定になり得るところ。
何が知りたいのかわかんないけど、自分で試せば?

25 名前:5 mailto:sage [2016/01/25(月) 11:52:15.00 ID:2nNO2C2F.net]
糞コードをこんな感じに修正しました。どなたか採点していただけますか?
ideone.com/KYia26
修正点は以下です。
・weak_ptrをshared_ptrや参照に置き換えた
・一番親のAはBのリストをshared_ptrからunique_ptrに置き換えた

書いてて思ったのですが、今回のような複数のオブジェクトから参照されるオブジェクトをソートする場合は
スマポあるいは生ポを使う以外方法がないんではないでしょうか?

26 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 12:49:17.26 ID:MTh5r7jR.net]
>>22
構造体同士の代入は出来ても比較が出来ないのは、
アラインメントを合わせるためにパディングされている場合があるから。

それを強引にmemcmpで比較したところで、その部分に何が入ってるかが分からないのだから
比較結果は環境依存になる。

つまり、charが1バイト、intが4バイト、アラインメントが4バイトだと仮定すると
struct hoge {char a; int b;};

struct hoge {char a; char pad[3]; int b;};
と同じような構造体のマップになる。
んで、memsetで初期化した場合を除けばpadの部分に何が入ってるかが分からないから
e,f,gはtrueにもfalseにもなりうる。

27 名前:デフォルトの名無しさん [2016/01/25(月) 13:24:30.56 ID:yh3tfuOH.net]
vc2012だとbは全領域0になるのですがこれも環境依存ですか

28 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 13:32:21.82 ID:MTh5r7jR.net]
>>27
吐かれた機械語読んで、memset系の関数呼んでれば実行環境には依存せず全0になるね。
でもコンパイラに依存するって意味では(ソースコードが)環境に依存してる。

c++のn3337の5.17.9には
an assignment to a scalar, in which case the initializer list shall have at most a single element. The
meaning of x={v}, where T is the scalar type of the expression x, is that of x=T(v) except that no
narrowing conversion (8.5.4) is allowed. The meaning of x={} is x=T().
って書かれてるから、規格上はbとcは見かけ上同じ値になる事になってるけど
vcは標準規格を守ってないので有名だから実際にどうなるかは知らない。

29 名前:デフォルトの名無しさん [2016/01/25(月) 13:42:36.07 ID:MTh5r7jR.net]
>>25
・shared_ptr(new T())はmake_shared<T>()で置き換えられる。
特に、Tのコンストラクタが例外を発生しうるなら常に置き換えるべき。
・vector同士の代入はその時点での配列のコピーになるからvector自体もshared_ptrで管理するべき。
C2にC1のリストを渡した後でC1が更新されると不整合が起こる。
・ラムダ式の引数の型にはauto系が使える。
幾つかの例外を除けば、型名としてはauto&&を使うのが楽。
・計算式に複数の副作用を含むべきではない。評価順序によって値が変わる可能性がある。
・listC2の要素数が1つでない場合にlistC1の更新が誤ったものになっている。

以上をてきとーに直すとこんな感じ。誰か追加の添削よろ
ideone.com/AUc7NI

30 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 14:44:01.36 ID:ZbEt+NlS.net]
>>29
横からすまん

>>25
>特に、Tのコンストラクタが例外を発生しうるなら常に置き換えるべき。

これなんで?



31 名前:5 mailto:sage [2016/01/25(月) 15:06:09.85 ID:2nNO2C2F.net]
>>29
すみません、一点大事なことをいい忘れてました。
BのlistC1はC2のそれとは同じでなく、後者は前者の部分集合で、C2オブジェクト間でlistC1の関連はなく、ソートも必要ないのでした。

いただいたアドバイスを元に改良しました。
ideone.com/nog6AP
(いくつかC++14の機能があったので、自分のC++11環境でビルドが通らなくて焦りました)

ところで、以下が分かりませんでした。よければもう少し教えていただけますか?

・計算式に複数の副作用を含むべきではない。評価順序によって値が変わる可能性がある。
・listC2の要素数が1つでない場合にlistC1の更新が誤ったものになっている。

32 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 16:14:27.17 ID:MTh5r7jR.net]
>>30
f(new T());
の実行は、
Tの為の領域が確保されて、
Tのコンストラクタが走った後に、
Tにとってのthisがfの為の引数としてスタックに積まれるかなんかして、f関数内で束縛できるようになる。

Tのコンストラクタが例外を投げると、fは走らずに例外がcatchされる。そしてthisが宙ぶらりんになって誰からも開放出来なくなる。
これを防ぐには、領域を確保した後それを何らかの変数に代入して、その後にTのコンストラクタが走るようにコードを書かなきゃならない。
これはplacement newを使うとこう書ける。
t = malloc(sizeof(T)); new (t) T();

で、make_sharedはTのコンストラクタがコケてもちゃんと開放するようにしっかり書いてる可能性が高い。
一方でshared_ptr(new T());だとTのコンストラクタがコケるとメモリリークが起こる。
そういった理由。

33 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 16:35:28.74 ID:MTh5r7jR.net]
>>31
> 計算式に複数の副作用を含むべきではない。評価順序によって値が変わる可能性がある。
これは、元コードの
vector<shared_ptr<C1>> l = { b->add_C1(1), b->add_C1(0), b->add_C1(2) };
について言ってて、この場合は(initializer listの場合は)左から順にっつーか出現順に評価される事が仕様で決まってるけど(8.5.4.4より)、
これがただの関数呼び出しの場合、つまり
initialize(l, b->add_C1(1), b->add_C1(0), b->add_C1(2));
みたいに書いた場合には左から順に評価されるとは限らない。だから気をつけてねって話。

> listC2の要素数が1つでない場合にlistC1の更新が誤ったものになっている。
これは元コードの
auto& c2 = b->add_C2(0);
c2->set_listC1(l);
の部分だね。add_C2が1度だけ呼ばれるならこのコードでも問題ないけど、
n回呼ばれうる事を考えるとfor文で全体を括った方が良いんじゃない?ってだけの話。

34 名前:デフォルトの名無しさん [2016/01/25(月) 16:38:44.03 ID:3jdDpl0p.net]
そのC2/C3の属性はC1が含むべきじゃないの?
なんか設計ぶっ壊れてんね

35 名前:デフォルトの名無しさん [2016/01/25(月) 16:50:27.54 ID:3jdDpl0p.net]
とりあえずC2/C3をタイプオブジェクトパターンにすればいいんじゃね

36 名前:5 mailto:sage [2016/01/25(月) 17:24:17.41 ID:2nNO2C2F.net]
>>33
>ただの関数呼び出しの場合には左から順に評価されるとは限らない
全く知りませんでした。超大事なことですね。
ありがとうございます。

>n回呼ばれうる事を考えるとfor文で全体を括った方が良いんじゃない?
仰る通り、実際の用途ではそうしてます。

37 名前:5 mailto:sage [2016/01/25(月) 17:37:21.34 ID:2nNO2C2F.net]
>>34
いえ、クラスの親子関係、およびメンバにコンテナや親への参照(生ポ、スマポ、参照のどれにするかは別として)を持つこと自体は間違いない設計です。

>>35
タイプオブジェクトパターンとは何でしょうか?
デザインパターンにはないようですが、Factoryパターンの一種でしょうか?

38 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 18:04:37.05 ID:3jdDpl0p.net]
>>37
れっきとしたデザパタ
www.cs.ox.ac.uk/jeremy.gibbons/dpa/typeobject.pdf

つかデータ同士の関連付けすぎじゃね
とりあえずC2、C3が必ずC1を含むなら、
C2/C3を汎化してC1の属性にしてBが持つのC1だけにして

C2、C3の各属性は速度が必要なら、C1用のツリーを汎化して、
C2とC3をBの操作とした方がスッキリすると思うんだけど
もしかしてC3やC2とC1の持つA/Bって別なん?

39 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 18:39:25.59 ID:6iy9dS6b.net]
>>25
https://ideone.com/xLFO7G
・オリジナルの変数の依存関係と丸出しスタイルはそのまま
・メソッド名とかは一部変えた
・生のポインタだけで運用
・deleteは一箇所で一括に行う
・もっとスッキリすると思ったが書いてみると意外とそうでもなかった

40 名前:5 mailto:sage [2016/01/25(月) 18:42:58.12 ID:2nNO2C2F.net]
>>38
>れっきとしたデザパタ
GoFのデザパタではないんですね。勉強します。

>とりあえずC2、C3が必ずC1を含むなら、
C3が含むのはC1ではなくC2です。IdeoneではC3は省いていますが。

>もしかしてC3やC2とC1の持つA/Bって別なん?
いえ、同じです。

実際のやりたいコードは2次元の幾何です。もっと早く言うべきだったかもしれません、すいません。
C1が点、C2が点を繋いだ線、C3が線で囲まれる多角形、BやAはそれらの上位のクラス(geometryみたいな名前)です。



41 名前:5 mailto:sage [2016/01/25(月) 18:57:41.09 ID:2nNO2C2F.net]
>>39
インスタンスを所持するテンプレートクラスを作るのですね。勉強になります。

42 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 19:12:59.35 ID:3jdDpl0p.net]
>>40
んーすまん、それでなんでこの設計になるのかわからん
とりあえずC1から取れるしC2/C3にA/Bのポインタいらないんじゃね

実現したいことがわからないが
幾何の表現なら一次元vectorで十分じゃね
index用vectorでn次元の部分集合の指定もできるし

43 名前:5 mailto:sage [2016/01/25(月) 20:00:38.31 ID:2nNO2C2F.net]
>>42
>とりあえずC1から取れるしC2/C3にA/Bのポインタいらないんじゃね
それは仰る通りです。
ただ、c2->listC1[0]->refB とC1を辿るのが面倒だったのでC2に持たせてしまいました。

>実現したいことがわからないが
うーん、そんな変でしょうか?
実は幾何の入出力ファイル(他者製)もこのクラスの親子関係そのままのフォーマットになってて、
それをコードでも踏襲したという経緯です。

44 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 20:18:32.30 ID:MTh5r7jR.net]
2次幾何の何がやりたいのか分からないって話じゃない?
接触判定でもしたいの?

45 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 20:28:56.97 ID:qUtW41iV.net]
>>26
ISO/IEC 14882:2014の8.5p6を読む限りパディングはビット0になると読めるのだが不定になると言う根拠は?

46 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 20:44:54.74 ID:qUtW41iV.net]
ちなみに8.5.1をさらりと読んだが
> hoge d = { 0, 0 };
に限ってはパディングがゼロ梅になるという記述が見つけられなかった

47 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 21:14:32.48 ID:3jdDpl0p.net]
>>43
>うーん、そんな変でしょうか?
変っていうかC1,C2,C3が何の表現なのかわからん

48 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 21:16:12.13 ID:MTh5r7jR.net]
うーん・・・・・・
確かによく読むと、x={}はx()に等しく、x()はvalue-initializedされて、
user provided constructorが存在しない場合はzero-initializerが走って、
その場合にはpaddingも0になるみたい。
規格準拠を仮定するなら君が正しい。嘘書いてごめんよ。

49 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 21:28:05.05 ID:3jdDpl0p.net]
>>45-46
そんなメガネクイーしてる暇あったら引用すりゃよくね?
>To zero-initialize an object or reference of type T means:
>...
>if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;
>if T is a (possibly cv-qualified) union type, the object’s first non-static named data member is zero initialized and padding is initialized to zero bits;

50 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 22:02:04.00 ID:aGf3VXDj.net]
>>45-46
>26 じゃないけど、
構造体のパディングバイトが全ビット 0 になる保証はあるんだけど、
int を 0 に初期化したときにパディングビットも含めて全ビットが 0 になる保証は見当たらないんだ。

パディングビットがある環境も少ないだろうし、あるとしても numeric_limits<int> とか調べれば事前に
有無が確認できるとは思うけど。



51 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 22:06:48.30 ID:aGf3VXDj.net]
>>32
> Tのコンストラクタが例外を投げると、fは走らずに例外がcatchされる。そしてthisが宙ぶらりんになって誰からも開放出来なくなる。
...
> 一方でshared_ptr(new T());だとTのコンストラクタがコケるとメモリリークが起こる。

んなこたーない。
www.kijineko.co.jp/tech/superstitions/memory-leak-at-dynamic-creation-fail.html

52 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 22:11:13.46 ID:aGf3VXDj.net]
>>39
> A *a(int i) {return as.add(new A(i));}
add() の中の push_back() で例外飛んだらリークする。
変な独自コンテナラッパーなんか作らないでおとなしくスマートポインタ使えばいいのに。

53 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 22:45:59.01 ID:u8HkWBJk.net]
>>30
こういう誤りによるメモリリークを根絶するため
new自体がソースコード上に現れるのを避けるのが普通
f(unique_ptr<A>(new A), unique_ptr<B>(new B));

ちなみにコンストラクターの例外は関係無い

54 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 22:51:40.35 ID:MTh5r7jR.net]
>>51
これは知らなかった。

それ自身のdtorは走らないみたいだから、fopenしてたり生のポインタ使ってたりすると危ないかも。
ideone.com/IOYMAt

55 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 22:55:07.69 ID:ATEV5j5o.net]
>>52
> push_back() で例外飛んだら

www.cplusplus.com/reference/vector/vector/push_back/
> If a reallocation happens, the storage is allocated using the container's allocator,
> which may throw exceptions on failure (for the default allocator,
> bad_alloc is thrown if the allocation request does not succeed).

↑これのこと?

56 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 22:57:30.92 ID:aGf3VXDj.net]
>>55 うん。

57 名前:5 mailto:sage [2016/01/25(月) 23:27:49.38 ID:2nNO2C2F.net]
>>31により当初の目的だったweak_ptrの排除ができ、またスマポの使用が今回の場合
不適切というわけではなさそう(というか自分的にはベストな解)ことが分かり
満足したので、質問を締めさせていただきます。

回答くれた方どうもありがとうございました。

58 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 23:46:30.78 ID:u8HkWBJk.net]
>>50
パディングビットの規定を探したらCにたどり着いた
これでよい?
C++ 3.9.1p3 Fundamental types
→ C言語 5.2.4.2.1 Size of integer types
→ C言語 6.2.6 Representations of types
→ C言語 6.2.6.2.5p5 Integer types
『The values of any padding bits are unspecified.』

59 名前:デフォルトの名無しさん mailto:sage [2016/01/25(月) 23:59:58.70 ID:aGf3VXDj.net]
>>58
そんなところ。
Cでも保証は無いよね。あったところでC++で「保証」とはいえないんだけど。

60 名前:デフォルトの名無しさん [2016/01/26(火) 00:41:34.27 ID:LScUQqmU.net]
>>57
とりあえずOpenGLとか触ったほうが良いと思います



61 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 00:45:45.80 ID:GVbqnwMe.net]
>>60
なんで?

62 名前:デフォルトの名無しさん [2016/01/26(火) 00:55:25.80 ID:LScUQqmU.net]
>>61
データ構造が見えてなさそうだから

63 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 01:15:04.16 ID:88T0+SoF.net]
3D空間上でvertexはedgeを、edgeはfaceを、faceはelementを構成するっていうデータ構造はごく普通でしょう
むしろ>>42みたいに全部vectorでやれとかいうほうがおかしい

64 名前:デフォルトの名無しさん [2016/01/26(火) 01:20:06.74 ID:LScUQqmU.net]
>>63
内包させるのは普通じゃないよ

65 名前:デフォルトの名無しさん [2016/01/26(火) 01:25:45.01 ID:LScUQqmU.net]
というか
>vertexはedgeを、edgeはfaceを、faceはelementを構成するっていうデータ構造はごく普通でしょう
こんなの見たこと無いよ
普通は各々verticesとして持ってるでしょ

66 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 01:29:56.87 ID:88T0+SoF.net]
>各々verticesとして持ってる
意味がわからない
elementとかの定義をvertexのリストだけでやるの?
tetraやhexaならいいけどpolyhedronはどうするの?

67 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 01:38:32.76 ID:usMbn1Xz.net]
「普通」とか「おかしい」とか主観でモノを言っちゃうからめんどうなことになる。
>63はそういう構造をよく使う、あるいはよく見る。
>65はそういう構造を見たことが無い。
それだけのことなら相手に合意を迫る必要はまったく無い。
同じものを作ってるなら話は認識あわせに意味があるかもしれないけど、
ここじゃアカの他人なんだからそんなこともあるじゃろ、でおしまい。
二人とも、もう寝たほうがいいよ。

68 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 01:38:35.41 ID:zaDrFWLK.net]
メッシュ変形なんかやるときは別だけど
OpenGLで表示させるだけなら普通は頂点とインデックス列だけで事足りる

69 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 02:02:32.36 ID:88T0+SoF.net]
そっかごめん
自分機械設計屋なんだけど、流体シミュレーションだとpolyhedron要素があるんで
こういうデータの持ち方するのよね
OpenGLは使ったことないっす

70 名前:デフォルトの名無しさん [2016/01/26(火) 02:53:27.61 ID:LScUQqmU.net]
多面体使う人でもEdge主体の構造じゃないのか?
まあもういいや大した話じゃないし



71 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 07:13:49.17 ID:8rZ+8lOF.net]
そこそこまっとうなことを言っているのに理解されなかった>>63が哀れ(チーン)

72 名前:デフォルトの名無しさん [2016/01/26(火) 07:26:37.18 ID:RIXqMqyc.net]
結局パディングはUMRんですか

73 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 13:43:58.10 ID:CloTf5dE.net]
>>71
書き方が悪いんだよな
プログラマの思考と反対というか

elementは複数のfaceで構成され
faceは複数のedgeで構成され
edgeは複数のvertexで構成される

ていう書き方の方がよかったと思われ

74 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 15:23:46.68 ID:VGU1ghG/.net]
>>73
いや、表現の問題じゃないでしょw
ちなみに俺はそっちより>>63のボトムアップ的な発想の方が自然

あんまり階層構造つくって持ちまわるよりは
フラットにしたほうが結局ラクなんじゃないかって発想には
俺も個人的には同意する

75 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 16:05:26.42 ID:MwP9iauO.net]
継承を行うと親クラスのコンストラクタが隠蔽されてしまうのですが、
コンストラクタが継承されないこの仕様にはなにか深い訳があるのでしょうか。

多重継承が関係しているような気もするのですが、
そもそも単一継承のJavaも同様の仕様なのでもっと根本的な理由があるのだと思うのですが。

76 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 16:07:43.83 ID:MwP9iauO.net]
すみませんサンプルの貼り付けを忘れていました。
ideone.com/v8QQHq

77 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 16:29:07.16 ID:uqIl8Fge.net]
>>75-76
サンプル 10 行目の注釈はないものとして

struct X : public Base {
 X(int i) : Base::Base(i) {} // 子から間接的に呼び出す必要がある
};

と書くのはいかんの?
Base() だけで自動的に Base::Base() を呼んで欲しいってことかな。

78 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 16:39:57.28 ID:XdnYao0l.net]
派生クラスをインスタンス化するときに派生クラスのコンストラクタは
呼び出さないで基底クラスのコンストラクタを直接呼び出したい?
そんなこと出来ないのは当たり前なのだが
そんなことしたくなる深い訳の方が気になる

79 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 16:40:10.39 ID:CloTf5dE.net]
例えば有名なモデリングソフトのメタセコイアのMQOファイルはモデルを>>73みたいに記述してあるよ
ただしedgeは無く、面は複数の頂点で表現されてたが

エレメントが複数の面で構成されるのは仕方ないし
面が複数の頂点で構成されるのも仕方ないように思うが

なんでもフラットな方が便利なのは常識だが
一体どうやってフラットにするのか興味があるわ

struct face{ int elem_no; float v[16][3]; int v_size; };
vector<face> faces;

こんなデータ構造じゃ、特定のエレメントだけ抜き出すのが大変だし
さらにもっとフラットにして

struct vertex{ int elem_no; int face_no; float v[3]; };
vector<vertex> vertices;

こんな構造にしちゃうと、かなりフラットになるが、面単位で何かするのに
まず同じface_noに属する頂点を探し回らなきゃならなくて超面倒なんだが
さらにもっとフラットにすると

struct vertex_elem{ int elem_no; int face_no; int vertex_no; int x_y_z_flag; float value; };

さすがにこれは無いか

80 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 16:48:50.66 ID:XdnYao0l.net]
X(int i) : Base(i) {}
を書くのが面倒くさいということか?
それを自動生成するのは条件を絞れば可能かも知れんが余計に分けわからなくなりそう



81 名前:77 mailto:sage [2016/01/26(火) 16:51:07.74 ID:uqIl8Fge.net]
>>77 は勇み足だった。C++11だと下のように書くか。

#include <iostream>
using namespace std;

struct Base {
int i;
Base(int i) : i {i} { cout << "ok! I got " << i << endl; }
};

struct X : public Base {
X(int i) : Base {i} {} // Base::Base() でなく
};

int main() {
X x {1}; // Base側のコンストラクタを呼べるでしょ
cout << "Yes, x.i == " << x.i << endl;
return 0;
}


明示的なコンストラクタ呼び出しでなく {} による初期化。

82 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 17:13:30.76 ID:MwP9iauO.net]
>>80
そうです、Baseを継承する派生クラスが沢山ある場合が面倒です。
コンストラクタの継承が行われれば、派生クラス側でわざわざ決まりきったコンストラクタを書かずに済むのでコードがシンプルになるなのですが、
それが出来るオブジェクト思考言語は意外と少ないです。

83 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 17:37:45.67 ID:5mNKNaDj.net]
>>82
class B {
public B() {System.out.println(

84 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 17:39:33.39 ID:JvvEVEHG.net]
ダブルクォーテーションで途切れるの悔しい…

>>82
class B {
public B() {System.out.println(”B”);}
public B(int i) {System.out.println(”B i”);}
}
class D1 extends B {} // 自動的に追加されるコンストラクタ内で暗黙的にsuper()
class D2 extends B {public D2(int i) {}} // 暗黙的にsuper()
class D3 extends B {public D3(int i) {super(i);}}
のとき
new D1();new D2(1);new D3(1);
でそれぞれ
B, B, B iを表示
Javaだと引数無しのときだけチョッと手間省けるね

85 名前:84 mailto:sage [2016/01/26(火) 17:46:54.81 ID:LDY5A4Ql.net]
ごめん、今確かめたらそれはC++でも一緒だったw
struct Base {
int i;
Base() : i(0) { cout << ”ok!”; }
};
struct X : public Base {};
これで X x; は普通に行けたねw

86 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 17:50:26.64 ID:XdnYao0l.net]
>>82
なるほど。それなら分かるわ
基底クラスのコンストラクタはある意味継承されてるんだけど
protected(ちょっと違うけど)みたいな扱いになってるんだよな
何かキーワードとかであなたの言う意味での継承が出来てもよい気がしてきた

87 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 18:41:50.54 ID:/Dc76BnU.net]
>>75
釣りは要らん
その内 コンストラクターの継承も知らないのかバーカバーカ
と言うんだろ?

88 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 19:55:14.89 ID:XdnYao0l.net]
釣られたわ
C++11から出来るようになってるね
ideone.com/PwOSrY

89 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 20:04:25.08 ID:yZwoVaS8.net]
>>88
それで十分に嬉しいように見えるんだけど
using Base::Base;の一行を書くのは>>75的には
「子から間接的に呼び出す必要がある」に該当しないのかな?

あと>>77が何を言っているのか意味不明なの俺だけ?

90 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 21:25:05.76 ID:I8Y70xN6.net]
>>51
これってコンストラクタ中から例外飛んで来たらいずれにせよメモリリークするから無駄って解釈でいいの?
この例だとdeleteはされるけど、結局デストラクタが呼ばれるわけじゃないからメンバにポインタ混じっててnewしてたりするとリークするよな



91 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 21:52:07.33 ID:8rZ+8lOF.net]
構築が終わっていない中途半端な状態でデストラクターが呼ばれたらそれこそ大変だ
少しは脳みそ使った方がいいぞ

92 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 22:52:14.01 ID:IXu06oBB.net]
C++ではインスタンスxのコンストラクタ内で例外が発生した場合、
xのデストラクタは呼ばれない(理由は>>91の通り
という言語仕様なのは真実なので、逃げ手としてnewに細工がしてあるだけの話

生のハンドルとかはこれそのものでは救えない。
コンストラクタで生のハンドルを確保するコードを普通に書いたら、コンストラクタが例外を生じたときにリークする

それを避けるための正しいテクニックは、
1) きちんとハンドル(リソース)のwrapperを書いて、
2) そいつをxのメンバにしとく
である(メンバのデストラクタは、xのコンストラクタが例外を生じても呼ばれる

んまー常識的には「コンストラクタで例外を発生させない」とか「例外が発生したら諦める」設計のが
特殊な用途以外では普通な希ガス、

93 名前:92 mailto:sage [2016/01/26(火) 22:56:25.94 ID:IXu06oBB.net]
>>92プチ訂正
s/コンストラクタ内で例(が|を)発生/コンストラクタから例外をスローさせない/g

コンストラクタ内で例外が発生しそうなところはtry { } catch { }で囲ってしまうのも一つの手ではある

94 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 22:58:40.82 ID:usMbn1Xz.net]
>>90
RAII の徹底ができていなければリークする可能性が出てくる。
例外の発生がコンストラクタからかどうかはあんまり関係ない。

95 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 23:02:54.28 ID:RBo8KHcc.net]
やはりバカにはC++の敷居が高いようだな

96 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 23:05:13.87 ID:8rZ+8lOF.net]
ラッパーを使うのは王道な一つの手だが
一つの関数内で例外安全なコードを書いてればリークは起こらない。
それすら出来ないようでは他の言語を使った方がいい

「コンストラクタで例外を発生させない」と言うのはやや方向性が違っていて
「プログラムを書かなければリークは起こさない」レベルの思考

97 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 23:06:58.14 ID:zcSlqmoV.net]
>>95
自己紹介はしなくていいぞ

98 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 23:12:32.60 ID:I8Y70xN6.net]
じゃあもしライブラリとして提供されてるクラスがメンバに複数ポインタ持っててコンストラクタで複数newして、しかもメモリが足りなくなる可能性が結構高い場合はどうすりゃいいんだ?
他のライブラリ使うのはいろんな理由で無理、ライブラリの互換性のために元のソースいじれないってなったら漏れたらあきらめるしかないのか?

99 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 23:14:58.68 ID:8rZ+8lOF.net]
例外安全でない糞ライブラリの中身をいじれない場合はどうすればよいの?

質問しなきゃわからないほど馬鹿なのか

100 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 23:22:01.99 ID:I8Y70xN6.net]
>>99
今まさに近い状況になってて、例外飛んでくるのはまた別の原因なんですけど
実際どうすればいいんですか?自分一人だけライブラリ使わないってのはできないんですけど



101 名前:デフォルトの名無しさん mailto:sage [2016/01/26(火) 23:23:01.51 ID:CloTf5dE.net]
まぁでもコンストラクタの途中で例外が発生しても
コンストラクタの中でtry-catchして適切にリソース開放すれば良いだけでは?






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

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

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