C++相談室 part122at TECH
C++相談室 part122 - 暇つぶし2ch1:デフォルトの名無しさん
16/01/23 23:06:15.32 HdItgJjm.net
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。
前スレ
C++相談室 part121
スレリンク(tech板)

このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.97【環境依存OK】
スレリンク(tech板)
次期規格C++1zはこちら
C++14/C++1z 20
スレリンク(tech板)
■長いソースを貼るときはここへ。■
 URLリンク(codepad.org)
 URLリンク(ideone.com)

2:デフォルトの名無しさん
16/01/23 23:07:25.42 HdItgJjm.net
[C++ FAQ]
URLリンク(isocpp.org)
URLリンク(www.bohyoh.com) (日本語)

3:デフォルトの名無しさん
16/01/23 23:11:46.68 HdItgJjm.net
STLつかうと一気に実行ファイルサイズが10倍に?!
環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない
すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?
#include <stdafx.h>
後死ね。
言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。

4:デフォルトの名無しさん
16/01/23 23:14:12.22 HdItgJjm.net
---- テンプレ ここまで ----

5:デフォルトの名無しさん
16/01/24 02:28:04.57 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:デフォルトの名無しさん
16/01/24 08:22:51.32 TFTujVHZ.net
どのタイミングでB,C1,C2,C3が作られるのかが分からないとコメントできない
最初に結合考えられてない状態で全部オブジェクトが作られてそのあとつながっていくパターンなのか、
それとも親が子を作るパターンしかありえないのかで話は変わる
あとクラスの階層って表現は基本的にクラスの派生・クラスの上位下位って意味で使われるから、そういう場合はノードの親子関係とかそういう言葉を使った方がいい

7:デフォルトの名無しさん
16/01/24 11:39:36.09 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:デフォルトの名無しさん
16/01/24 13:20:32.74 6/siiwPN.net
ファミコン世代なのでbelongs toって言い回しが怖くて使えない…

9:デフォルトの名無しさん
16/01/24 13:26:35.94 efwl3LYy.net
All your base are belong to us

10:デフォルトの名無しさん
16/01/24 14:29:49.80 7wa58CB+.net
>>8
何で?

11:デフォルトの名無しさん
16/01/24 16:17:33.38 6/siiwPN.net
>>10
All your base are belongs to us.
これ訳せる?

12:デフォルトの名無しさん
16/01/24 16:30:11.35 7wa58CB+.net
>>11
そんな英語を書いちゃうのが怖いってこと?
それとも英語圏だと有名な言い回しか何かってこと?
ごめん、文法詰め込み教育受けた典型的な日本人なんで、訳せないす…

13:5
16/01/24 16:51:59.34 0LR1dPfv.net
>>6
>最初に結合考えられてない状態で全部オブジェクトが作られてそのあとつながっていくパターンなのか、
最初は何も考えずそうしていました。つまり、全てのオブジェクトをshared_ptrで作っていました。
ただ、前スレの指摘からshared_ptrを意味もなく使うのは駄目だと悟ったので、
ノード間に自明な親子関係があることから、素直に「親が子を作る」ほうがいいかと思いました。
>>7
書き忘れましたが、全てのクラスはインデックスを表すメンバ int index を持っており
これに従ってvectorをソートしたいのでした。
こういう場合shared_ptrやweak_ptrを使うのは悪くないということでしょうか?

14:デフォルトの名無しさん
16/01/24 18:26:26.83 LHp2Xjej.net
>>13
最終的に何をやりたいかにもよる。
全てのノードへのポインタをunordered_setで保持して、確保するときは必ずそのunordered_setにinsertし、ノード間は生のポインタを使う
なんて実装も可能で、場合によってはその方が実行速度が速い。
BはA以外からは所有されないのであれば、shared_ptrよりunique_ptrの方が意味的には適切。

15:デフォルトの名無しさん
16/01/24 18:34:36.48 fkWZRTEw.net
>確保するときは必ずそのunordered_setにinsert
挿入が随分とマヌケなコードにならないか?

16:デフォルトの名無しさん
16/01/24 18:36:18.10 fkWZRTEw.net
あ、間違えた失礼

17:デフォルトの名無しさん
16/01/24 18:38:12.34 LHp2Xjej.net
関数なりマクロなりに隠すから問題ない
ホントの事いってunordered_setなんぞあんまり使ったこと無いんだけど、大体こんなイメージ
T* my_new(unordered_set<T*>& heap) {
auto t = new T;
heap.insert(t);
return t;
}

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

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

20:デフォルトの名無しさん
16/01/24 21:56:44.58 ssnQMLKn.net
>>12
有名な間違いだらけの英語

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

22:デフォルトの名無しさん
16/01/25 10:55:34.57 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
16/01/25 11:17:27.48 2nNO2C2F.net
>>18
問題は全くないです。
ただ、スマポを正しく使えてる自信がなかった中、前スレ>>956等を見てやばいと焦った次第です。
>>14
生ポインタ使うのは正直抵抗があるので今回は見送ります。
unique_ptrは仰る通り使うべきでした。

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

25:5
16/01/25 11:52:15.00 2nNO2C2F.net
糞コードをこんな感じに修正しました。どなたか採点していただけますか?
URLリンク(ideone.com)
修正点は以下です。
・weak_ptrをshared_ptrや参照に置き換えた
・一番親のAはBのリストをshared_ptrからunique_ptrに置き換えた
書いてて思ったのですが、今回のような複数のオブジェクトから参照されるオブジェクトをソートする場合は
スマポあるいは生ポを使う以外方法がないんではないでしょうか?

26:デフォルトの名無しさん
16/01/25 12:49:17.26 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:デフォルトの名無しさん
16/01/25 13:24:30.56 yh3tfuOH.net
vc2012だとbは全領域0になるのですがこれも環境依存ですか

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

30:デフォルトの名無しさん
16/01/25 14:44:01.36 ZbEt+NlS.net
>>29
横からすまん
>>25
>特に、Tのコンストラクタが例外を発生しうるなら常に置き換えるべき。
これなんで?

31:5
16/01/25 15:06:09.85 2nNO2C2F.net
>>29
すみません、一点大事なことをいい忘れてました。
BのlistC1はC2のそれとは同じでなく、後者は前者の部分集合で、C2オブジェクト間でlistC1の関連はなく、ソートも必要ないのでした。
いただいたアドバイスを元に改良しました。
URLリンク(ideone.com)
(いくつかC++14の機能があったので、自分のC++11環境でビルドが通らなくて焦りました)
ところで、以下が分かりませんでした。よければもう少し教えていただけますか?
・計算式に複数の副作用を含むべきではない。評価順序によって値が変わる可能性がある。
・listC2の要素数が1つでない場合にlistC1の更新が誤ったものになっている。

32:デフォルトの名無しさん
16/01/25 16:14:27.17 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:デフォルトの名無しさん
16/01/25 16:35:28.74 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:デフォルトの名無しさん
16/01/25 16:38:44.03 3jdDpl0p.net
そのC2/C3の属性はC1が含むべきじゃないの?
なんか設計ぶっ壊れてんね

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

36:5
16/01/25 17:24:17.41 2nNO2C2F.net
>>33
>ただの関数呼び出しの場合には左から順に評価されるとは限らない
全く知りませんでした。超大事なことですね。
ありがとうございます。
>n回呼ばれうる事を考えるとfor文で全体を括った方が良いんじゃない?
仰る通り、実際の用途ではそうしてます。

37:5
16/01/25 17:37:21.34 2nNO2C2F.net
>>34
いえ、クラスの親子関係、およびメンバにコンテナや親への参照(生ポ、スマポ、参照のどれにするかは別として)を持つこと自体は間違いない設計です。
>>35
タイプオブジェクトパターンとは何でしょうか?
デザインパターンにはないようですが、Factoryパターンの一種でしょうか?

38:デフォルトの名無しさん
16/01/25 18:04:37.05 3jdDpl0p.net
>>37
れっきとしたデザパタ
URLリンク(www.cs.ox.ac.uk)
つかデータ同士の関連付けすぎじゃね
とりあえずC2、C3が必ずC1を含むなら、
C2/C3を汎化してC1の属性にしてBが持つのC1だけにして
C2、C3の各属性は速度が必要なら、C1用のツリーを汎化して、
C2とC3をBの操作とした方がスッキリすると思うんだけど
もしかしてC3やC2とC1の持つA/Bって別なん?

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

40:5
16/01/25 18:42:58.12 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
16/01/25 18:57:41.09 2nNO2C2F.net
>>39
インスタンスを所持するテンプレートクラスを作るのですね。勉強になります。

42:デフォルトの名無しさん
16/01/25 19:12:59.35 3jdDpl0p.net
>>40
んーすまん、それでなんでこの設計になるのかわからん
とりあえずC1から取れるしC2/C3にA/Bのポインタいらないんじゃね
実現したいことがわからないが
幾何の表現なら一次元vectorで十分じゃね
index用vectorでn次元の部分集合の指定もできるし

43:5
16/01/25 20:00:38.31 2nNO2C2F.net
>>42
>とりあえずC1から取れるしC2/C3にA/Bのポインタいらないんじゃね
それは仰る通りです。
ただ、c2->listC1[0]->refB とC1を辿るのが面倒だったのでC2に持たせてしまいました。
>実現したいことがわからないが
うーん、そんな変でしょうか?
実は幾何の入出力ファイル(他者製)もこのクラスの親子関係そのままのフォーマットになってて、
それをコードでも踏襲したという経緯です。

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

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

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

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

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

49:デフォルトの名無しさん
16/01/25 21:28:05.05 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:デフォルトの名無しさん
16/01/25 22:02:04.00 aGf3VXDj.net
>>45-46
>26 じゃないけど、
構造体のパディングバイトが全ビット 0 になる保証はあるんだけど、
int を 0 に初期化したときにパディングビットも含めて全ビットが 0 になる保証は見当たらないんだ。
パディングビットがある環境も少ないだろうし、あるとしても numeric_limits<int> とか調べれば事前に
有無が確認できるとは思うけど。

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

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

53:デフォルトの名無しさん
16/01/25 22:45:59.01 u8HkWBJk.net
>>30
こういう誤りによるメモリリークを根絶するため
new自体がソースコード上に現れるのを避けるのが普通
f(unique_ptr<A>(new A), unique_ptr<B>(new B));
ちなみにコンストラクターの例外は関係無い

54:デフォルトの名無しさん
16/01/25 22:51:40.35 MTh5r7jR.net
>>51
これは知らなかった。
それ自身のdtorは走らないみたいだから、fopenしてたり生のポインタ使ってたりすると危ないかも。
URLリンク(ideone.com)

55:デフォルトの名無しさん
16/01/25 22:55:07.69 ATEV5j5o.net
>>52
> push_back() で例外飛んだら
URLリンク(www.cplusplus.com)
> 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:デフォルトの名無しさん
16/01/25 22:57:30.92 aGf3VXDj.net
>>55 うん。

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

58:デフォルトの名無しさん
16/01/25 23:46:30.78 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:デフォルトの名無しさん
16/01/25 23:59:58.70 aGf3VXDj.net
>>58
そんなところ。
Cでも保証は無いよね。あったところでC++で「保証」とはいえないんだけど。

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

61:デフォルトの名無しさん
16/01/26 00:45:45.80 GVbqnwMe.net
>>60
なんで?

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

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

64:デフォルトの名無しさん
16/01/26 01:20:06.74 LScUQqmU.net
>>63
内包させるのは普通じゃないよ

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

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

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

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

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

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

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

72:デフォルトの名無しさん
16/01/26 07:26:37.18 RIXqMqyc.net
結局パディングはUMRんですか

73:デフォルトの名無しさん
16/01/26 13:43:58.10 CloTf5dE.net
>>71
書き方が悪いんだよな
プログラマの思考と反対というか
elementは複数のfaceで構成され
faceは複数のedgeで構成され
edgeは複数のvertexで構成される
ていう書き方の方がよかったと思われ

74:デフォルトの名無しさん
16/01/26 15:23:46.68 VGU1ghG/.net
>>73
いや、表現の問題じゃないでしょw
ちなみに俺はそっちより>>63のボトムアップ的な発想の方が自然
あんまり階層構造つくって持ちまわるよりは
フラットにしたほうが結局ラクなんじゃないかって発想には
俺も個人的には同意する

75:デフォルトの名無しさん
16/01/26 16:05:26.42 MwP9iauO.net
継承を行うと親クラスのコンストラクタが隠蔽されてしまうのですが、
コンストラクタが継承されないこの仕様にはなにか深い訳があるのでしょうか。
多重継承が関係しているような気もするのですが、
そもそも単一継承のJavaも同様の仕様なのでもっと根本的な理由があるのだと思うのですが。

76:デフォルトの名無しさん
16/01/26 16:07:43.83 MwP9iauO.net
すみませんサンプルの貼り付けを忘れていました。
URLリンク(ideone.com)

77:デフォルトの名無しさん
16/01/26 16:29:07.16 uqIl8Fge.net
>>75-76
サンプル 10 行目の注釈はないものとして
struct X : public Base {
 X(int i) : Base::Base(i) {} // 子から間接的に呼び出す必要がある
};
と書くのはいかんの?
Base() だけで自動的に Base::Base() を呼んで欲しいってことかな。

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

79:デフォルトの名無しさん
16/01/26 16:40:10.39 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:デフォルトの名無しさん
16/01/26 16:48:50.66 XdnYao0l.net
X(int i) : Base(i) {}
を書くのが面倒くさいということか?
それを自動生成するのは条件を絞れば可能かも知れんが余計に分けわからなくなりそう

81:77
16/01/26 16:51:07.74 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:デフォルトの名無しさん
16/01/26 17:13:30.76 MwP9iauO.net
>>80
そうです、Baseを継承する派生クラスが沢山ある場合が面倒です。
コンストラクタの継承が行われれば、派生クラス側でわざわざ決まりきったコンストラクタを書かずに済むのでコードがシンプルになるなのですが、
それが出来るオブジェクト思考言語は意外と少ないです。

83:デフォルトの名無しさん
16/01/26 17:37:45.67 5mNKNaDj.net
>>82
class B {
public B() {System.out.println(

84:デフォルトの名無しさん
16/01/26 17:39:33.39 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
16/01/26 17:46:54.81 LDY5A4Ql.net
ごめん、今確かめたらそれはC++でも一緒だったw
struct Base {
int i;
Base() : i(0) { cout << ”ok!”; }
};
struct X : public Base {};
これで X x; は普通に行けたねw

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

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

88:デフォルトの名無しさん
16/01/26 19:55:14.89 XdnYao0l.net
釣られたわ
C++11から出来るようになってるね
URLリンク(ideone.com)

89:デフォルトの名無しさん
16/01/26 20:04:25.08 yZwoVaS8.net
>>88
それで十分に嬉しいように見えるんだけど
using Base::Base;の一行を書くのは>>75的には
「子から間接的に呼び出す必要がある」に該当しないのかな?
あと>>77が何を言っているのか意味不明なの俺だけ?

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

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

92:デフォルトの名無しさん
16/01/26 22:52:14.01 IXu06oBB.net
C++ではインスタンスxのコンストラクタ内で例外が発生した場合、
xのデストラクタは呼ばれない(理由は>>91の通り
という言語仕様なのは真実なので、逃げ手としてnewに細工がしてあるだけの話
生のハンドルとかはこれそのものでは救えない。
コンストラクタで生のハンドルを確保するコードを普通に書いたら、コンストラクタが例外を生じたときにリークする
それを避けるための正しいテクニックは、
1) きちんとハンドル(リソース)のwrapperを書いて、
2) そいつをxのメンバにしとく
である(メンバのデストラクタは、xのコンストラクタが例外を生じても呼ばれる
んまー常識的には「コンストラクタで例外を発生させない」とか「例外が発生したら諦める」設計のが
特殊な用途以外では普通な希ガス、

93:92
16/01/26 22:56:25.94 IXu06oBB.net
>>92プチ訂正
s/コンストラクタ内で例(が|を)発生/コンストラクタから例外をスローさせない/g
コンストラクタ内で例外が発生しそうなところはtry { } catch { }で囲ってしまうのも一つの手ではある

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

95:デフォルトの名無しさん
16/01/26 23:02:54.28 RBo8KHcc.net
やはりバカにはC++の敷居が高いようだな

96:デフォルトの名無しさん
16/01/26 23:05:13.87 8rZ+8lOF.net
ラッパーを使うのは王道な一つの手だが
一つの関数内で例外安全なコードを書いてればリークは起こらない。
それすら出来ないようでは他の言語を使った方がいい
「コンストラクタで例外を発生させない」と言うのはやや方向性が違っていて
「プログラムを書かなければリークは起こさない」レベルの思考

97:デフォルトの名無しさん
16/01/26 23:06:58.14 zcSlqmoV.net
>>95
自己紹介はしなくていいぞ

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

99:デフォルトの名無しさん
16/01/26 23:14:58.68 8rZ+8lOF.net
例外安全でない糞ライブラリの中身をいじれない場合はどうすればよいの?
質問しなきゃわからないほど馬鹿なのか

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

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

102:デフォルトの名無しさん
16/01/26 23:23:51.29 4LzhB3JY.net
例外処理でメモリリークを気にしたりするのがナンセンスなんよ
例外起きたらあとはリソース閉じて終了するだけのことだから
アプリケーションとしては終了に向かうだけだからリークも糞もないんよ

103:デフォルトの名無しさん
16/01/26 23:27:16.38 XdnYao0l.net
>>100
ライブラリがバグってるならどうしょうもないだろ
>>102
ずいぶんとおめでたい世界にいらっしゃるようで

104:デフォルトの名無しさん
16/01/26 23:28:08.68 sH2SZupb.net
コンストラクタで例外が発生したらそのクラスの何を解放するんだ

105:デフォルトの名無しさん
16/01/26 23:28:59.31 4LzhB3JY.net
mallocに失敗したのにexit前にfreeを呼びたい
みたいな不思議な連中は一定おるんよ

106:デフォルトの名無しさん
16/01/26 23:30:11.03 8rZ+8lOF.net
>>101
おおまかにはそれでよいが
最低限 例外中立にしとくのがマナー
具体的にはfunction-try-blockを使うかthrow;で再スローするかラッパーを使うか

107:デフォルトの名無しさん
16/01/26 23:30:13.68 sH2SZupb.net
例外発生する=アプリを終了するってなんなんだよ

108:デフォルトの名無しさん
16/01/26 23:30:33.16 XdnYao0l.net
>>104
例外発生するまでに確保済みのリソース
そんな面倒なことにならないようにRAIIの徹底はもう必須だよ

109:デフォルトの名無しさん
16/01/26 23:31:01.96 CloTf5dE.net
ちなみにnewしたオブジェクトのコンストラクタ内で例外が発生した場合
デストラクタは走らないけどoperator deleteは呼ばれるからメモリリークしないよ

110:デフォルトの名無しさん
16/01/26 23:34:08.88 TGWAfBDP.net
>>98
その通りだよ。

111:デフォルトの名無しさん
16/01/26 23:38:07.07 8rZ+8lOF.net
>コンストラクタ内で例外が発生した場合デストラクタは走らない
揚げ足を取ると、走るケースが全くない訳ではない

112:デフォルトの名無しさん
16/01/26 23:44:41.90 usMbn1Xz.net
>>111 ほんとならくわしく。

113:デフォルトの名無しさん
16/01/27 00:02:05.29 zgyqI55G.net
>>112
コンストラクタ内で例外が発生してもコンストラクタ内でキャッチしてしまえば走らない
コンストラクタ内で例外が発生してもコンストラクタ内でキャッチしてしまえば走らない

114:デフォルトの名無しさん
16/01/27 00:02:50.96 zgyqI55G.net
ごめwwwwwwww
走るの間違いwwwwwwwwww

115:デフォルトの名無しさん
16/01/27 00:04:30.16 0q1DRp6s.net
触れないソースのリソースリークなんて気にしても仕方ないだろ
気持ち悪いけど放っておけ

116:デフォルトの名無しさん
16/01/27 00:13:07.10 zgyqI55G.net
普通に使ってリソースリークの危険があり、
かつユーザーの立場からリークを阻止する手段が無いというのは
ライブラリのバグと言って過言ではない

117:デフォルトの名無しさん
16/01/27 00:34:28.52 zSFGO6dq.net
いや普通にバグだから

118:デフォルトの名無しさん
16/01/27 00:47:13.92 tYkYQITg.net
それでお客様が納得してくれるとでも?

119:デフォルトの名無しさん
16/01/27 00:52:40.92 0q1DRp6s.net
仕様ですの一点張り

120:デフォルトの名無しさん
16/01/27 01:45:10.90 zgyqI55G.net
>>100
longjump()か例外をthrowするかして大域脱出すると良い
ID:I8Y70xN6が。

121:デフォルトの名無しさん
16/01/27 02:00:29.05 gidaw1Ah.net
コンストラクタ内でtry catch 再throwでいいんだろ?
何も難しいことなんてないじゃない。

122:デフォルトの名無しさん
16/01/27 03:05:27.95 3jiwec3B.net
>>113
なるほどな
ちなみにコンストラクターから例外が漏れた場合でもデストラクターは走る事がある
struct A {
 A() {}
 A(int) : A() {throw 0;}
 ~A() {}
};
int main() {
 A a{0};
}

123:デフォルトの名無しさん
16/01/27 06:38:25.30 oAun2w+9.net
>>121
つ初期化子

124:デフォルトの名無しさん
16/01/27 07:11:47.54 3jiwec3B.net
>>123
初期化しがどうかしたか?
カタコトではただのアスペだぞ

125:デフォルトの名無しさん
16/01/27 07:34:44.55 T1kNk2gL.net
>>108
それはそのクラスが内部で処理することであってユーザーは何を解放するんだよ

126:デフォルトの名無しさん
16/01/27 08:01:41.14 7tk5IOS7.net
↑こんなところにアスペがもう一人

127:デフォルトの名無しさん
16/01/27 10:47:19.58 oAun2w+9.net
>>124
コンストラクタ初期化子

128:デフォルトの名無しさん
16/01/27 12:30:07.60 eULyfEEH.net
>>125
>それはそのクラスが内部で処理することであって
ずっとその話なのだが

129:デフォルトの名無しさん
16/01/27 12:56:11.97 zSFGO6dq.net
初期化子もそうだけどデフォルトコンストラクトされる変数もそうだな
コンストラクタ内でtry-catchできない
やっぱりコンストラクトでの例外はまずいんじゃないか?

130:デフォルトの名無しさん
16/01/27 13:59:04.99 oAun2w+9.net
C++17ではできるんだっけ?

131:デフォルトの名無しさん
16/01/27 17:48:02.83 gidaw1Ah.net
初期化子リストもメンバ変数も関係なくね?
初期化しきれたクラスはデストラクタが呼ばれ、初期化できなかったクラスは内部でcatchしてエラー処理して再送するだけ。
やっぱ単純だよ。
我らがMeyer先生はなんて言ってるの?

132:デフォルトの名無しさん
16/01/27 18:08:44.32 7tk5IOS7.net
>>129
できないと判断した根拠は?
URLリンク(ideone.com)
>>131
メイヤー「ワシ、ちょっとC++引退するわ」

133:デフォルトの名無しさん
16/01/27 18:10:24.29 7tk5IOS7.net
一カ所訂正

try m{}, x{}

try : m{}, x{}

134:デフォルトの名無しさん
16/01/27 18:15:50.95 7tk5IOS7.net
>>127
荒らしは去れ

135:デフォルトの名無しさん
16/01/27 18:45:02.79 oAun2w+9.net
>>131
コンストラクタ初期化子に書くメンバーが初期化はコンストラクタのスコープ内部じゃない。
自作クラスだったら君の言うように内部catchすればいいけど他作クラスで例外をthrowするタイプだtry-catchで囲めない。

136:デフォルトの名無しさん
16/01/27 18:49:38.11 oAun2w+9.net
>>134
まさか14以降を前提にしてるなんて言うまい?

137:デフォルトの名無しさん
16/01/27 19:31:29.47 3jiwec3B.net
>>136
お前はコンストラクター初期化子や例外という言語機能がC++14以降だとでも言いたそうだな
どれだけ勉強不足なんだ

138:デフォルトの名無しさん
16/01/27 19:39:57.53 6XO7CsMP.net
お前らに一度確認していい?
初期化リストつったらコンストラクタのパラメータのカッコの横の
クラス名(引数) : この部分 {}
を言うんだよな?
駆け出しの頃にC++プライマーとかいう分厚い本で学んだときは
たしかこうだったはずなんだが
std::initializer_listの出現で落ち着かない気持ちになってきてる

139:デフォルトの名無しさん
16/01/27 19:53:14.68 3jiwec3B.net
>初期化リストつったら
(中略)
>を言うんだよな?
いやまずそこから違う

140:デフォルトの名無しさん
16/01/27 20:04:51.00 1b0Lj9r3.net
クラス名(引数) : この部分は初期化子 {}

141:デフォルトの名無しさん
16/01/27 20:41:04.94 aFoLhF8M.net
>>140
とんくす!
↓少し学んだ
ISO/IEC 14882:1998
12.6.2 Initializing bases and members
ctor-initializer:
 : mem-initializer-list
mem-initializer-list:
 mem-initializer
 mem-initializer , mem-initializer-list
mem-initializer:
 mem-initializer-id ( expression-listopt )
mem-initializer-id:
 ::opt nested-name-specifieropt class-name
 identifier

142:デフォルトの名無しさん
16/01/27 20:44:21.08 gqKHFo+S.net
>>129
だからtry-catchなんかしない。>>94,108のとおりRAIIで解決する。
なんというか10年前にタイムスリップした感がある。↓読んでくれ。
URLリンク(www.google.co.jp)

143:デフォルトの名無しさん
16/01/27 21:00:23.97 zSFGO6dq.net
>>132
あなたのおっしゃる通りです。いい加減なこと言ってごめんなさい魔が差しましたw
やはり大事なのはRAIIの徹底ですね

144:デフォルトの名無しさん
16/01/27 21:08:05.10 oAun2w+9.net
>>137
えっ?
初期化子までtry説に含めるのはC++11ではできないって言いたいだけなんだけど?

145:デフォルトの名無しさん
16/01/27 21:09:24.27 oAun2w+9.net
×try説
○try節

146:デフォルトの名無しさん
16/01/27 21:10:04.69 0xRCKJUw.net
RAIIって初期化がキモみたいなネーミングだけどデストラクタの解放の方が大事じゃね

147:デフォルトの名無しさん
16/01/27 21:13:01.64 1b0Lj9r3.net
>>141
ああ、構文規則の非終端記号名のmem-initializer-listと混同していたのか。

148:デフォルトの名無しさん
16/01/27 21:16:28.24 3jiwec3B.net
>>144
ISO/IEC 14882:1998 15p1 8行目
ISO/IEC 14882:2003 15p1 8行目
ISO/IEC 14882:2011 15p1 8行目
ISO/IEC 14882:2014 15p1 8行目
これのどこを読んだらいったいそんな嘘が出てくるのか

149:デフォルトの名無しさん
16/01/27 21:19:58.24 hY0OCllE.net
だからHaskell使えと言っとるだろがボケ。

150:デフォルトの名無しさん
16/01/27 21:23:34.50 zSFGO6dq.net
>>144
俺はあなたに釣られちゃったけどこれが真実です
URLリンク(ideone.com)

151:デフォルトの名無しさん
16/01/27 21:26:16.20 Qr5LJlmv.net
このスレって常連の2、3人がID変えながら互いを罵ってんだよな?

152:デフォルトの名無しさん
16/01/27 21:27:35.65 3jiwec3B.net
>>150
C++14の結果のようだが
コミュ障は去れ

153:デフォルトの名無しさん
16/01/27 21:28:27.16 oAun2w+9.net
>>148
えっえっ?!?!
今の今まで「14になったら使える機能か楽しみだ」と思ってた...

154:デフォルトの名無しさん
16/01/27 21:30:40.94 hs0c0BKx.net
> C++14の結果のようだが
そこは突っ込むのが正解なのかw
なんか深遠な理由があるのか
高度な釣りなのかわかりかねたわ(>>144に対してC++14の結果貼り付け)

155:デフォルトの名無しさん
16/01/27 21:33:45.85 0q1DRp6s.net
初期化子って何だ?
もしかしてメンバイニシャライザのこと?

156:デフォルトの名無しさん
16/01/27 21:36:46.74 0q1DRp6s.net
>>153
Exceptional C++に出てくるぐらいにはメジャーだったはずだぞ

157:デフォルトの名無しさん
16/01/27 21:40:42.54 3jiwec3B.net
>>155
それはですね
狡猾な>>140が初期化子リストとメンバー初期化子とコンストラクター初期化子を混同した>>138を惑わすために出した用語なんです気にしないで
ちなみに規格ではnew A(100)とかの『(100)』の部分を指します

158:デフォルトの名無しさん
16/01/27 21:40:46.23 5WlKM79a.net
>>155
> メンバイニシャライザ
それちなみにどこで習ったの?
どこの流儀?

159:デフォルトの名無しさん
16/01/27 21:42:32.38 zSFGO6dq.net
>>152
はあそんなところに突っ込まれるとはw
>>153
あなたはC++14でもだめでC++17になったら出来るかもって思ってたでしょw

160:デフォルトの名無しさん
16/01/27 21:43:28.66 oAun2w+9.net
申し訳ない。釣りではなく本当にfunction-try-blockはこれから来る規格だと思っていた。
>>156
持ってるけどそんな記述あったかな?

161:デフォルトの名無しさん
16/01/27 21:43:53.84 3jiwec3B.net
>>158
>>141を100回読み直してこい

162:デフォルトの名無しさん
16/01/27 21:45:04.77 0q1DRp6s.net
>>158
流儀?
メンバ変数の初期化を行うのはmember initializerだぞ

163:デフォルトの名無しさん
16/01/27 21:46:53.21 gqKHFo+S.net
>>150
> B() try : _id(GetId()), _a(_id)
> {
> cout << "B:B" << _id << endl;
> }
> catch(int ex)
> {
> cout << "B:B" << _id << " exception " << ex << endl;
このcatch内でのメンバ変数 _id の参照は未定義動作になる。
15.3 [except.handle] p10
> Referring to any non-static member or base class of an object in the
> handler for a function-try-block of a constructor or destructor for that
> object results in undefined behavior.

164:デフォルトの名無しさん
16/01/27 21:47:25.50 0q1DRp6s.net
>>160
お前絶対読んでないだろw

165:デフォルトの名無しさん
16/01/27 21:48:01.49 VHRBi97o.net
>>162
ごめんごめん、純粋に何でその名前を学んだか知りたかっただけ
上でも書いたけど俺はC++プライマーって本を読んで学んだんだけど
たしかそれは 初期化リスト って書いてあったはずなんだ(多分)
だからみんなソレをどこで学んで何と呼んでるのか気になっただけ

166:デフォルトの名無しさん
16/01/27 21:49:15.00 oAun2w+9.net
多分、なんか大昔の記事を読んで最新のものと勘違いしたまま来てしまったのだ...
鬱だ

167:デフォルトの名無しさん
16/01/27 21:51:52.82 zSFGO6dq.net
>>163
ごめん
その点は危ういと思ったけどGCCだと取り敢えず意図通りになってたから
話の本筋的にはどうでもいいと思っちゃった

168:デフォルトの名無しさん
16/01/27 21:52:17.67 0q1DRp6s.net
すまん見直したらMoreの方だったw

169:デフォルトの名無しさん
16/01/27 21:52:25.06 3jiwec3B.net
>>163
そういやそんな決まりがあったな
すっかり忘れてた

170:デフォルトの名無しさん
16/01/27 21:54:30.71 oAun2w+9.net
>>168
安心した。ありがとう。
俺が持ってるのは2000年11月15日発行とある。
みなさん、すいませんでした。

171:デフォルトの名無しさん
16/01/27 21:54:40.52 88/bqypu.net
みんな企画とか読んでるのか偉いですね
1ページも読んだことないわ

172:デフォルトの名無しさん
16/01/27 22:01:47.89 0q1DRp6s.net
>>170
Moreも2001年なんだから安心するなよw
その頃からメジャーどころは載ってたはずだ

173:デフォルトの名無しさん
16/01/27 22:10:37.63 0q1DRp6s.net
>>165
あまり意識したことはないので
恐らくコンパイラのメッセージだな
規格も読んだが後付けだと思う

174:デフォルトの名無しさん
16/01/27 22:13:35.94 oAun2w+9.net
鬱だ

175:デフォルトの名無しさん
16/01/27 22:15:41.80 jBJgujTM.net
>>173
> 恐らくコンパイラのメッセージだな
なるほどなるほど!
こういうレスをついにもらえて俺喜んでる

176:デフォルトの名無しさん
16/01/27 22:27:11.15 vltUk2i7.net
ここは罵倒したりされたりを楽しむ変態スレ。
記憶でレス→お前バカか→バカはお前→証拠だオラ→悪ぃ悪ぃw
これが挨拶みたいなもん。
一度した発言は曲げてはならないという。

177:デフォルトの名無しさん
16/01/27 22:35:48.89 zgyqI55G.net
RAIIは論理的には正しいかもしれないが
記述量の割に得られる対価が例外に対する備えだけ、
というのが気に入らない
RAIIなプログラムのメモリ消費量はなかなか安定に達しないから(∵確保したり開放したりで断片化が進んだり治まったり、
意図とはうらはらに、実は第三者に対してメモリリークが無いことの証拠提示がヒジョーに厄介なプログラムになってしまったりする

178:デフォルトの名無しさん
16/01/27 22:45:20.30 gqKHFo+S.net
>>177
隙だらけすぎるだろ。
> 記述量の割に得られる対価が例外に対する備えだけ、
基本的なところは標準ライブラリでカバーされてるんだけど、記述量ってどんなコード想定してんの?
それに、例外以外にreturnやbreakにも利くよ。
> RAIIなプログラムのメモリ消費量はなかなか安定に達しないから(∵確保したり開放したりで断片化が進ん
確保解放のパターンがRAIIで規定されるわけないし、使い方でどうにでもなるでしょ。
> 意図とはうらはらに、実は第三者に対してメモリリークが無いことの証拠提示がヒジョーに厄介なプログラムに
RAII使わない、生でdeleteやらなんやら書いてるコードよりはマシでしょ。悪化する例があるなら見たい。

179:デフォルトの名無しさん
16/01/27 22:49:16.44 zSFGO6dq.net
>>177
?それはおかしな見解だな
RAIIを徹底するほうが記述量も少なくなる(delete書かなくて済むんだから)し、
メモリリークが無いことも遥かに容易に証明できると思うが?
それで納得しない第三者なんて頭が腐ってるんだから相手にするだけ無駄
断片化については直接new、deleteするのと変わらないし

180:デフォルトの名無しさん
16/01/27 22:55:49.88 zgyqI55G.net
>>178
いちいちstd::shared_ptr<T>とか打ちたくないし、pSomeSmartPtr.get()ですらちょっと嫌
メモリ直接ならまだ標準ライブラリでカバーされるが、OSがハンドルを返す場合はwrapperを書かねばならない
そしてコンストラクタが例外をスローするのに処置しようとしたら、
漏れの無いtry { } catch { }を書くか、メンバ変数を全部wrapperかスマポにせねばならない
これは苦行以外の何者でもない
そしてクラスの群れを書く面々のうちの誰か一人がしくじれば、やはりリークする
returnやbreakについては、例外と違って伝統的な書き方で対処可能
例外はスマポとか、try { } catch { } みたいな仕掛けが要る

181:デフォルトの名無しさん
16/01/27 22:56:07.86 3jiwec3B.net
記述量は局所的な見た目の煩雑さのことを言ってるのだろうに
トータルの記述量の話にすり替えとはこれ如何に

182:デフォルトの名無しさん
16/01/27 22:59:19.51 zgyqI55G.net
>>179
>そしてクラスの群れを書く面々のうちの誰か一人がしくじれば、やはりリークする
この危険性についてコードを見るだけで検証完了という信じる方がよっぽどキチ
同じコードを見る話なら、固定長の配列の方が安心できる

183:デフォルトの名無しさん
16/01/27 23:00:49.72 0xRCKJUw.net
あらゆる箇所にいちいちdelete Tとか打ちたくないわ

184:デフォルトの名無しさん
16/01/27 23:04:15.53 zgyqI55G.net
>>183
もちろんナマポも極力使わない
やっても関数内で確保したやつを関数を抜けるとき全部開放する使い方のみとしたい(この用途にはstd::unique_ptr<T>を使ってやっても良い
この構造に統一するなら、メモリの断片化は生じない(まあだれか一人がしくじれば…というのは同じだが

185:デフォルトの名無しさん
16/01/27 23:07:10.32 zSFGO6dq.net
なんだ固定長配列至上主義者か
せいぜい頑張って下さい

186:デフォルトの名無しさん
16/01/27 23:08:36.16 3jiwec3B.net
>この危険性についてコードを見るだけで検証完了という信じる方がよっぽどキチ
文脈を考慮して読み解かなくても局所的なコード確認の積み重ねのみで全体に漏れがないことを保証できるのがRAIIだと思っていたのだが…

187:デフォルトの名無しさん
16/01/27 23:13:29.29 zgyqI55G.net
加えてRAIIにはマルチコア時代にふさわしくない疑いがある
RAIIで確保したり開放したるするメモリがスレッド固有という保証が無い限り、
確保や開放の度に排他制御が行われる
スタック上にとられた配列がペナルティーゼロであることを鑑みれば、
InterlockedIncrement()ですら塵も積もれば巨大なコスト足りえる

188:デフォルトの名無しさん
16/01/27 23:18:25.90 zSFGO6dq.net
そんなにヘビーなループで確保/解放を繰り返さなきゃいけない場面では俺だってダイナミックアロケーションを避けるけどね

189:デフォルトの名無しさん
16/01/27 23:20:30.30 eULyfEEH.net
>>187
言っていることがよくわからないね
shared_ptrのコストが気になるならnewせずに
スタック上に確保するなりなんなりすればよいだけだろうに
そっちの方が正統派のRAIIだというのに何を言っているのだろうか
まったくお門違い
むしろスタック上にオブジェクトを確保できる言語の方が珍しくて
C++ではそれができるだけでも有り難いというのに

190:デフォルトの名無しさん
16/01/27 23:20:47.91 I7Q8DIXY.net
 普段よりも応用を利かせたコードの書き方の検討をして、まだ知識があいまいなところ
をはっきりさせようと、本で調べ物をしてたら、「プログラミング言語 第3版」よりも、
「C++ Primer 改訂3版」のほうが、はっきりと疑問に答えてくれると感じた。応用で検討
していることが可能になるか、それとも無理かをすぐに結論を出してくれるみたいな。
もう一方の本は、ストラウストラップ流のプログラム技術の英知を読者に提供しようとは
してるようだけど、仕様で細かいところを素早く確認するのはまだ物足りないかもしれな
いな。

191:デフォルトの名無しさん
16/01/27 23:21:41.35 3jiwec3B.net
>スレッド固有という保証が無い限り、
確保や開放の度に排他制御が行われる
>スレッド固有という保証が無い限り、
確保や開放の度に排他制御が行われる
>スレッド固有という保証が無い限り、
確保や開放の度に排他制御が行われる
ひょっとしてRAII=shared_ptrとでも勘違いしたのだろうかこの馬鹿は 👀
Rock54: Caution(BBR-MD5:0be15ced7fbdb9fdb4d0ce1929c1b82f)


192:デフォルトの名無しさん
16/01/27 23:26:34.20 I7Q8DIXY.net
 今は「プログラミング言語 第4版」が新しく出たようだけど、今はC++14らしいが、
この本はC++11のようで、編集が一歩遅れてるという印象は否めない。
 読者はC++14準拠の第5版を望んでるかもしれないな。

193:デフォルトの名無しさん
16/01/27 23:27:07.17 0q1DRp6s.net
>>177
>記述量の割に得られる対価が例外に対する備えだけ
さすがにこれはないわなあ
今更RAII無しでlockとか絶対使いたくない

194:デフォルトの名無しさん
16/01/27 23:47:08.39 0q1DRp6s.net
ここまで俺の自演

195:デフォルトの名無しさん
16/01/27 23:47:41.22 tYkYQITg.net
前にEffectiveC++も新版が出たけど、もう絶対的な名著ってわけでもないような

196:デフォルトの名無しさん
16/01/27 23:52:26.77 gqKHFo+S.net
>>180
10年ぐらい前にはこんな爺さんがよく居たもんだが、まだ居るのか・・・。
> いちいちstd::shared_ptr<T>とか打ちたくないし、pSomeSmartPtr.get()ですらちょっと嫌
慣れる。どうしても嫌なら好きに using でもしとけばいい。 get() なんて使わんでいい。
> メモリ直接ならまだ標準ライブラリでカバーされるが、OSがハンドルを返す場合はwrapperを書かねばならない
自分で書くケースがあるのはそうだが、稀だろ。
稀じゃないなら、個別に破棄処理を漏れなく書いて回るよりも一度書けば済むRAIIのほうがマシ。
> メンバ変数を全部wrapperかスマポにせねばならない
> これは苦行以外の何者でもない
std::shared_ptr<T>が打てない状況ならそうかもしれないな。
でもそれは個人的な事情であってRAIIの問題じゃない。
> そしてクラスの群れを書く面々のうちの誰か一人がしくじれば、やはりリークする
RAII関係ない。
> returnやbreakについては、例外と違って伝統的な書き方で対処可能
伝統的で且つ面倒な書き方でな。RAIIのほうが楽。

197:デフォルトの名無しさん
16/01/27 23:54:32.28 0q1DRp6s.net
>>195
古いのは確かだがまだ十分使えると思うね
他に初心者用の良い本があれば別だけど

198:デフォルトの名無しさん
16/01/27 23:57:30.71 0q1DRp6s.net
スマポはgoogleやmozillaのソース見ればそこらじゅうにあるな
それを全部書き下せる自身があるならどうぞ

199:デフォルトの名無しさん
16/01/28 00:38:12.26 5VmqP1pO.net
>>132
絶望した!
>>135
いやいや、初期化子に並んでるクラスまでtryで囲む必要ないでしょ?
彼らは彼らで後始末するのだから。
自分の後始末せずに例外投げるクラスがいたら、どんな手段を使ったって後始末できないよ。
コンストラクタに限る問題じゃない。

200:デフォルトの名無しさん
16/01/28 01:13:22.83 9zxCdjKY.net
>>199
後始末したあと例外を投げて来るやつをcatchするんじゃない?

201:デフォルトの名無しさん
16/01/28 06:48:43.02 OteWNMPZ.net
RAIIってなんて発音するの?
ライー? ラッツー?

202:デフォルトの名無しさん
16/01/28 07:29:19.73 y2I8o1dH.net
ラール

203:デフォルトの名無しさん
16/01/28 07:37:04.01 WeC7vVSZ.net
ライッ!

204:デフォルトの名無しさん
16/01/28 07:41:40.98 y2I8o1dH.net
>>199
catch(...)

205:デフォルトの名無しさん
16/01/28 08:26:24.97 5VmqP1pO.net
>>204
言葉足らずですまんが、自分が言及した自分自身の後始末っていうのはそのクラス内部の後始末のこと。
ハードを止めるとかメンバのメモリ開放とか。
使う側のクラスは後始末しないクラスの内部のことなんてわからないから、どんな手段を使ったってそのクラスの後始末はできない。
だから、そんなクラスがいることを前提として議論するのはおかしいってこいいたかったわけ。
そのクラスの提供者に直してもらうしかない。

206:デフォルトの名無しさん
16/01/28 08:35:58.09 9zxCdjKY.net
>>205
それは正しいが、そこが論点じゃないと思う。
コンストラクタ内でエラーが起きたとき、「後始末はちゃんとやったあと例外をthrowする」クラスに
対処することを想定してる。

207:デフォルトの名無しさん
16/01/28 08:51:24.46 5VmqP1pO.net
>>206
対処する必要なんてあるの?
繰り返すけど、
初期化子で構築完了したクラスはデストラクタで後始末されて、例外吐いたクラスも自身のtrycatch再throwで後始末してるんだぜ?
親側自身の雑多な初期化処理は始まってもいない。
…と書いてみたが、自分が間違ってるわ。
これで対応できない例外シチュもあり、そんな場合は個別対応すればよいだろうとは思ってたけど、例外とは呼べないほどそんな場面は多い気がしてきた。

208:デフォルトの名無しさん
16/01/28 09:29:37.28 ptM8I7fQ.net
>>207
「これで対応できない例外シチュ」ってどんなの?

209:デフォルトの名無しさん
16/01/28 11:10:21.47 5VmqP1pO.net
>>208
dispose()とかclose()みたいな関数を呼んでやらないと終了処理できないやつ。

210:デフォルトの名無しさん
16/01/28 11:21:23.95 ptM8I7fQ.net
>>209
fclose や fstream みたいな、能動的操作処理と破棄処理が不可分になってるもののことかな。
そういうクラスをメンバを持つクラスのコンストラクタで例外が出たとした場合に行う「個別対応」って、
たとえばどんなの?
デストラクタが最低限の処理をしてくれてれば何もしなくていいケースがほとんどだと思うんだけど。

211:デフォルトの名無しさん
16/01/28 13:13:16.79 5VmqP1pO.net
>>210
終了処理がsendfinとかwaittimeoutとかだったりしたら、デストラクタで勝手にやられたら困らね?
非対称的に終了処理関数が用意されてることも少なくないと思う。
バグなら直せと言えるけど、設計いけてないから直せとはなかなか要求しにくい。

212:デフォルトの名無しさん
16/01/28 13:56:52.11 tIrgtpz+.net
デストラクタでfcloseとか何ですのん?
ファイル操作をオブジェクトの寿命で扱うのって大掴みすぎねぇ?
だからコンストラクタやデストラクタでそんなもんの例外までに話が至っちまう
書き込む瞬間、読み無瞬間だけ一瞬だけファイルを開けや
そこまではバッファに書きこんどけや糞ども

213:デフォルトの名無しさん
16/01/28 14:51:57.24 Fy8z7rZ+.net
一つわかった
RAIIと例外を背反と考えてる人がいる

214:デフォルトの名無しさん
16/01/28 19:35:11.13 CFwd7jm1.net
>>212
ログライブラリを開発しているのですが
一瞬だけ開くようにすると処理時間が100 倍以上
になって困っています。
どうすればよいですか?

215:デフォルトの名無しさん
16/01/28 19:59:05.52 9zxCdjKY.net
>>212
ファイル書き込みオブジェクトをファクトリ関数経由で
一時オブジェクトとしてしか生成できないようにしたことがある。
書き込んだらすぐデストラクタが走るのさ。

216:デフォルトの名無しさん
16/01/28 19:59:21.20 D7v4IB1O.net
バッファが無限にあると思ってる人に聞くだけ無駄

217:デフォルトの名無しさん
16/01/28 20:01:49.04 VbpHGgsr.net
>>215
kwsk

218:片山博文MZ ◆T6xkBnTXz7B0
16/01/28 20:02:05.39 YC3cOEYy.net
>>214
出力が遅いなら、キャッシュとして出力内容をためておけば

219:デフォルトの名無しさん
16/01/28 20:11:54.15 D7v4IB1O.net
アプリが落ちて肝心な最後のログレコードが見えないのでしたチャンチャン

220:デフォルトの名無しさん
16/01/28 21:05:31.79 DYq8nyhg.net
ログを安易にバッファリングする奴は間違いなく低能

221:デフォルトの名無しさん
16/01/28 23:03:17.58 iP985GXo.net
自作プログラムのログを取る必要が未だ生じたことが無い天才かも知れん

222:デフォルトの名無しさん
16/01/28 23:07:22.96 YmAPLaNv.net
んなこたない
糞コテ=馬鹿 で決まり

223:デフォルトの名無しさん
16/01/28 23:11:59.87 iP985GXo.net
ログメッセージを複数スレッドから単一のコンソールに出す場合はcerrよりcoutの方がメッセージの1行同士が混ざる危険性が目に見えて減る
デバッグレベルならprintf()して何か条件を満たしたらfflush(stdout); throw;、が最強

224:デフォルトの名無しさん
16/01/28 23:17:33.09 Fy8z7rZ+.net
>>223
>ログメッセージを複数スレッドから単一のコンソールに出す場合はcerrよりcoutの方がメッセージの1行同士が混ざる危険性が目に見えて減る
気のせいだろ
マルチスレッドなら、素直に同期したほうが良いぞ

225:デフォルトの名無しさん
16/01/28 23:50:40.02 ptM8I7fQ.net
>>211
その困る場合の「対処」の例が聞きたかった。
デストラクタに嫌な終了処理が埋まってて困るという場合は対処のしようも無い
=結局何もしなくていいんじゃないの?
それで実用上の問題があるなら直せと言えるはず。
コンストラクタで例外が飛んだってことは問題の終了処理を持つオブジェクトを使って
やろうとしてた処理全体は失敗したわけで、正常処理の締めに必要な
終了処理( fstream で close() とか)の明示的呼び出しも必要ないことが多いだろうし。

226:デフォルトの名無しさん
16/01/29 19:24:04.25 dpjhh/AA.net
>>52
> > A *a(int i) {return as.add(new A(i));}
> add() の中の push_back() で例外飛んだらリークする。
これはpush_back()出来なかった分をケアしてやればおk?
URLリンク(ideone.com)
・天然のstd::bad_allocは得られなかったので誤魔化した

227:デフォルトの名無しさん
16/01/29 21:58:56.14 V57FZVNV.net
生ポ好きの書きそうな糞みたいなコードだな
↓こんなんでいいだろ
v.reserve(v.size() + 1);
v.push_back(new Fuck);

228:デフォルトの名無しさん
16/01/29 22:53:49.61 tuK26dsC.net
技術的な話題をせず
ブログラミングを種に喧嘩ばかりしてるやつって何なの
チンパンジーなの?

229:デフォルトの名無しさん
16/01/29 23:21:25.56 q1Jl0W+Y.net
いきなりどうした
誤爆か?

230:デフォルトの名無しさん
16/01/29 23:29:27.61 HWJSMXKP.net
>>227
そんな意味不明なreserveする奴が偉そうなこと言っても

231:デフォルトの名無しさん
16/01/29 23:35:27.84 ASWZHNV8.net
>>226
おじいちゃん、「おとなしくスマートポインタ使えば」おkだっていったでしょ。聞こえてる?

232:デフォルトの名無しさん
16/01/29 23:52:06.13 Hpd/92hj.net
>>230
いや意味が全く無いわけではない
std::vector::push_back()呼び出し時点での余分な領域確保とか、速度低下が最小化される

233:デフォルトの名無しさん
16/01/30 00:09:33.50 VhIzDspW.net
>>232
230 じゃないけど、 >227 の reserve() で「速度低下が最小化される」なんてことは無いでしょ。
単発なら変わらないだろうし、ループした場合は reserve() しないほうが速いし。

234:デフォルトの名無しさん
16/01/30 00:17:51.94 lYkNZO2m.net
>>232
ないない
push_backで領域が足りなければreserve相当のことは自動的にされるし
まあないだろうがstd::vectorの実装によってはsize()+1のreserveが速度に悪影響与えることだってあり得るんじゃないかな
>>227のもう一つ痛いところはreserveさえしておけばpush_backでの例外が無いと決めつけてるところ
そんな規定はないだろ?

235:デフォルトの名無しさん
16/01/30 00:21:53.24 nKxSIfYZ.net
>>234
> push_backでの例外が無いと決めつけてるところ
というより、それを一切考慮してない希ガスw
そいつ一人だけ問題の本質に到達できていない
bad_allocが投げられるのは一緒ってことも知らないんだろうし

236:デフォルトの名無しさん
16/01/30 00:55:16.18 GfziY506.net
はてどこからbad_allocが出てきたのか

237:デフォルトの名無しさん
16/01/30 03:14:53.57 HpDJFp9+.net
>>233>>234
漏れは慎重に「std::vector::push_back()呼び出し時点での」と限定して書いたで?

238:デフォルトの名無しさん
16/01/30 05:43:02.21 VhIzDspW.net
>>237
ん?だから何?
push_back() 関数内での領域確保・実行時間を減らして、それらを push_back() の
直前の処理に移動することに何か意味があるとでもいうの?それはどんな場合にうれしいの?

239:デフォルトの名無しさん
16/01/30 05:59:47.15 GfziY506.net
A「意味がないわけではない」
 「~される」
B「そんなことは ない」
A「そんなこと ある だろ」
B「だから何?~だと何かいいことあるのか?」
>>232の2つの文のどちらについて話をしているのかの認識がずれていることに気付かない低能どもの会話は滑稽だな

240:デフォルトの名無しさん
16/01/30 06:17:44.28 GfziY506.net
やっぱり馬鹿にC++は無理だな
メモリ確保のnew/deleteは禁止にしてスマポとコンテナーだけ使っとけ
ついでに馬鹿はshared_ptrも使用禁止にしといた方が安全

241:デフォルトの名無しさん
16/01/30 11:02:01.65 u8r8Wxi4.net
> v.reserve(v.size() + 1);
> v.push_back(new Fuck);
やっぱり馬鹿にC++は無理だなw
push_backの直前で+1サイズのreserveとかw
URLリンク(www.cplusplus.com)
ここのExampleみてお勉強しなおしたら?
例外投げるのも書いてくれるから学んどけよ

242:デフォルトの名無しさん
16/01/30 11:46:11.52 GfziY506.net
初回がresize前のcapacityと比較して何が言いたいのかよくわからん例だな
push_backはcapacityに余裕が有るときに再アロケーションしないことは保証されているが
例外を出さない保証は23.3.6.5から読みとれないな
やはり馬鹿にはスマポを強制したほうがいい

243:デフォルトの名無しさん
16/01/30 13:13:55.69 VK1fBsAo.net
>>238
reserve()とpush_back()のどちらで例外が発生するかという文脈において、
>>227のreserve()がpush_back()の直前行であるという解釈は一体…
まあv.reserve(v.size() + n);ならともかく、v.reserve(v.size() + 1);だったから気持ちはわからんでもない

244:デフォルトの名無しさん
16/01/30 14:18:45.97 GfziY506.net
どうみても>>227はpush_back(というかnew)の直前にしか見えないのに
何を言ってるんだお前は

245:デフォルトの名無しさん
16/01/30 15:00:28.25 9j1RlcoP.net
挿入前に拡張しておけという有難い教えだな。

246:デフォルトの名無しさん
16/01/30 16:17:33.41 GfziY506.net
>>245
挿入前に拡張すると(要素のコンストラクター以外では)例外が出ないという保証はある?

247:デフォルトの名無しさん
16/01/30 16:22:43.98 AurOqJPw.net
>>245 はC++とは違う話題かと。
Cとなら関係あるかも知れないが、プログラミング言語でないC。
もちろん俺の読み違いかもしれない。

248:デフォルトの名無しさん
16/01/30 16:27:26.60 7MlWNObS.net
あと一個で例外が飛ぶようなメモリ状況で
☆一行のとき
v.push_back(foo); // ここで例外
☆二行のとき
v.reserve(v.size() + 1); // ここで例外
v.push_back(foo);
こうなるだけじゃないの?
新たな連続した一本のメモリが確保できないと例外なんだから

249:デフォルトの名無しさん
16/01/30 16:35:52.43 lYkNZO2m.net
>>246
規格を読んだ限り保証はされてないね
現実に存在する実装ではreserve済みであれば生ポのpush_backじゃ例外発生しないだろうけどね
そんなことはアテにしちゃいけない

250:デフォルトの名無しさん
16/02/01 01:01:58.63 CuJD672c.net
reserveで例外かわせても、次のnewによるメモリ確保で例外になる可能性はなくならないのだから、
newを一旦別の変数で受けるしかないでしょ
hoge h;
h = new hoge;
vec.push_back(h);
が正解。

251:デフォルトの名無しさん
16/02/01 01:58:17.63 fnCrDph6.net
いやいやwもういいからスマポをmake_uniqueとかmake_sharedで使っておけ
バカはnewを書くな!

252:デフォルトの名無しさん
16/02/01 02:09:31.02 CuJD672c.net
>>251
あんたバカバカ言ってるけどnewを使うかmake_sharedを使うかはこの問題の本質じゃないから。
馬鹿じゃないならわかるよね?

253:デフォルトの名無しさん
16/02/01 02:22:38.94 dRJvSEmL.net
どうなんだろうね
vec.push_back( new t() )
の場合、newで例外が発生したらpush_backは実行しないんだから関係ないと思うんだが
push_back呼ぶ前の、スタックに引数を積む段階で例外が発生するわけだから
push_backは呼ばれもしないし、全く関係ないと思うんだが

254:デフォルトの名無しさん
16/02/01 02:25:49.77 fnCrDph6.net
>>252
あなたが問題の本質を理解してると思えないが?
newを変数で受けたってなにも変わりはしないよ
てか、まずはhoge* hにしてから言ってくれない?

255:デフォルトの名無しさん
16/02/01 05:14:31.96 yDMVnQCY.net
java厨ってnewしたままホウチミンだよね

256:デフォルトの名無しさん
16/02/01 06:43:17.15 JTo/Q0C3.net
>>250>>253のような
C++の教科書にある間違ったコードのテンプレのような糞コードを真顔で言い出す低能を見ると
やはり馬鹿にはスマポとしか言いようがない

257:デフォルトの名無しさん
16/02/01 17:11:12.73 Ev74Df4F.net
そのjava厨が何を指すのか曖昧だが
Javaでは普通、ネイティブリソースはRAIIで開放するぞ

258:デフォルトの名無しさん
16/02/01 17:14:07.57 /UrjTotH.net
ジャバってデストラクタみたいなの追加さらた?

259:デフォルトの名無しさん
16/02/01 17:59:52.82 fnCrDph6.net
JavaでRAIIとかもうわけがわかんねーな異世界に飛ばされたような感覚だよ

260:デフォルトの名無しさん
16/02/01 18:03:33.95 JTo/Q0C3.net
確かにJavaのRAIIはCloseableとAutoCloseableの違いを理解してないと正しく使いこなせないからな
>>259のオツムがフットーしてしまうのも致し方ない

261:デフォルトの名無しさん
16/02/01 19:47:56.26 FCPkKuCG.net
C++に移ってきたjava厨だよ
newしたままdeleteしねぇ糞ソース大量生成しやがる

262:デフォルトの名無しさん
16/02/01 20:09:02.04 qjT3Q9+K.net
>>261
Java厨は犬派で、C++厨は猫派だからな
newと鳴いたら、deleteるからな

263:デフォルトの名無しさん
16/02/01 20:24:37.67 ZBzDFClp.net
>>262
こういう喩え話って、短い文章中に多くの情報が込められてるものだが。
無粋を承知でお願いします。解説してください。

264:デフォルトの名無しさん
16/02/01 20:42:15.43 aUqGS129.net
>>261
Java 厨に生ポなんて使わせるお前が狂ってる

265:デフォルトの名無しさん
16/02/01 20:46:33.11 qjT3Q9+K.net
>>263
深い意味は無いよ
C/C++やるときはnewしたらdeleteせよ!って鉄則でしょ
ニャー(new)と鳴いたら、必ずデレてる(deleteる)からC++厨は猫派
単なるダジャレだよw

266:デフォルトの名無しさん
16/02/01 20:51:56.51 JTo/Q0C3.net
>newしたらdeleteせよ!って鉄則でしょ
低能のお前にはわからないかも知れないが
そんなことはない

267:デフォルトの名無しさん
16/02/01 21:00:17.78 fOHJkiXU.net
猫は飯くれと撫でろしか言わない
自分が人間より上だと思ってるのでデレることはない

268:デフォルトの名無しさん
16/02/01 21:32:50.64 JTo/Q0C3.net
>>264
ジャバ厨とレッテルを貼るのではなく、たまたまソイツが低能だからということに気付くべき
Javaでもリソース開放は行うし、C++スレにも>>250,>>252,>>253のようなメモリも開放できない奴もいる

269:デフォルトの名無しさん
16/02/01 21:42:26.29 BsHDgmsO.net
生ポってどんな場面で使うの?

270:デフォルトの名無しさん
16/02/01 22:07:54.53 wHu9vKIt.net
>>268
低脳な Java 使いだから Java 厨ってラベル貼られてることに気づくべき

271:デフォルトの名無しさん
16/02/01 22:57:12.27 47CQ9v48.net
>>269
ツリー構造で子が親へ参照を持つときに使ったことがあるな
相互参照するけど、親の寿命管理が必要が無いのでshared/weak_ptrが不要なケース
↓こんな感じ
class tree_view
{
tree_view *parent;
vector<unique_ptr<tree_view>> children;
};

272:デフォルトの名無しさん
16/02/01 23:10:37.79 BsHDgmsO.net
>>271
deleteの出番なしか

273:デフォルトの名無しさん
16/02/01 23:55:10.43 CuJD672c.net
>>268
だったら模範解答貼ってみせろよクズ

274:デフォルトの名無しさん
16/02/02 00:06:14.39 ygGmQV70.net
>>273 >>231

275:デフォルトの名無しさん
16/02/02 00:14:57.63 oBfAWjKR.net
>>271
子を作り管理するのは親ですか?

276:デフォルトの名無しさん
16/02/02 00:50:11.96 AUeQZlYi.net
生ポ渡しするなら生成するのは普通は親でも子でもなくファクトリだと思う

277:デフォルトの名無しさん
16/02/02 00:59:22.35 AUeQZlYi.net
生ポ渡しってただただ生ポ渡すってだけの意味な
こう書いとかないと馬鹿には使えないが口癖のボットに絡まれそうだし一応書いとくわ

278:デフォルトの名無しさん
16/02/02 01:25:45.50 x5amnXbs.net
>>260
へえJavaにもRAIIの概念なんてあったんだ
Javaな現場になんてもう何年も関わってないんで知らんかったわ

279:デフォルトの名無しさん
16/02/02 01:37:28.22 r5dd6eSW.net
沖林正紀の悲劇を繰り返すな

280:デフォルトの名無しさん
16/02/02 03:58:43.22 uTTEQY4N.net
罵倒してるやつの態度は悪いけど
例だろうとポインタ間違えた上に
今時newしてvectorにpush_backしちゃうようなコード書いて
その上逆ギレしちゃう奴は正直ダメだと思う

281:デフォルトの名無しさん
16/02/02 06:45:21.02 5quLb8ti.net
質問です。
URLリンク(ideone.com)
上の21行目の再解釈キャストで型変換してるところってVCでは意図したとおりに動いたのですが、
これって他の環境でも大丈夫ですか?

282:デフォルトの名無しさん
16/02/02 07:52:12.29 Vw/b/5l0.net
配列a[10]で&a==&a[0]となる理由がわかりません。
おしえてください。
&a[0]はaの要素の1番目の番地で&aはaの1番目の要素を
指し示すアドレスのアドレスの気がするからです。

283:デフォルトの名無しさん
16/02/02 07:59:56.34 N9T32bdW.net
アドレスのアドレスなんてものは無いということに気がつけばまぁそんなもんかと理解できるかと
(ポインタ変数のアドレスならある)

284:デフォルトの名無しさん
16/02/02 09:42:40.95 LvBWX7cX.net
例外機能をoffにした場合
std::vector<int> v(???);
でメモリの確保に失敗した場合の動作はどうなりますか

285:デフォルトの名無しさん
16/02/02 11:14:27.48 NoB4axe7.net
"自動車"クラスを"人間"クラスが操作するとします。
"自動車"クラスが提供する個々の機能(例えばアクセルやブレーキ)は、
サブクラスが提供(例えばアクセルはエンジンクラスに定義)して、
"自動車"クラスは特に関与しないものとします。
この前提において"自動車"クラスを定義する場合、"自動車"クラスは
サブクラスを継承するかたちで定義したほうが良いでしょうか?
それとも、自動車クラスが個々のサブクラスのインスタンスを保持して
メソッドをラップしたほうが良いでしょうか?

286:デフォルトの名無しさん
16/02/02 11:22:39.18 ygGmQV70.net
>>281
継承を確信できるところでのダウンキャストは static_cast の出番。 5.2.9 [expr.static.cast] p2
reinterpret_cast で作った結果に移植性があるのはごく一部だけ。 5.2.10 [expr.reinterpret.cast]

287:デフォルトの名無しさん
16/02/02 11:22:52.91 MIlHcyxr.net
人とエンジンは特性上車とは異質であるが為継承ではなくラップした方が融通性能高いことは明白である

288:デフォルトの名無しさん
16/02/02 11:23:10.07 ygGmQV70.net
>>282
いいかげんな教材には a が「配列先頭要素へのポインタである」などと
書いてあるかもしれないが、実際には「配列」であり一部の例外を除いて
「配列先頭要素へのポインタに暗黙変換される」ということになっている。
& 演算子は例外のひとつで、 &a で配列そのものへのポインタが得られる。
4 [conv] p8

289:デフォルトの名無しさん
16/02/02 11:23:22.64 ygGmQV70.net
>>284
非標準の動作なので、まずコンパイラのマニュアルを調べる。
書いてなければ、どうせ移植性は期待できないので実験でもいいかもしれない。

290:デフォルトの名無しさん
16/02/02 11:24:45.55 ygGmQV70.net
>>285
URLリンク(www.google.co.jp)

291:デフォルトの名無しさん
16/02/02 11:30:10.28 NTv/QStd.net
>>285
当然後者。
現実の関係を模倣するのが普通。
一点、ラップってのをどういう意図で使っているのかが気になる。
個々の部品を組み合わせて、車としての機能を提供すると考えてね。
部品の機能をスルーするだけのラッパーはあまり出ないはず。

292:285
16/02/02 11:53:42.81 NoB4axe7.net
皆さん、回答ありがとうございました。
継承と包含の関係を理解してませんでした。
ちなみに”サブクラス”という言葉の使い方も誤解してたみたいです(^^;
>>291
>ラップってのをどういう意図で使っている
部品の機能をスルーするだけのラッパーという意味でした (^^;
その辺も含めてもう少し設計を見直したいと思います。

293:デフォルトの名無しさん
16/02/02 13:09:09.90 ZM61xwKS.net
未だbetter Cより進んだ使い方ができない

294:デフォルトの名無しさん
16/02/02 13:26:24.18 7f7wf/mW.net
>>284
俺の環境だと、色々省略すれば
std::vector : protected std::_Vector_base {
vector(size_type __n, const allocator_type& __a = allocator_type()) : _Vector_base(__n, __a) { _M_default_initialize(__n); }
};
std::_Vector_base {
_Vector_base(size_t __n, const allocator_type& __a) { _M_create_storage(__n); }
};
となって、最終的に__gnu_cxx::__alloc_traits<_Alloc>::rebind<_Tp>::other::allocate() defined at ext/new_allocator.hが呼び出されて
pointer allocate(size_type __n, const void* = 0) {
if (__n > this->max_size()) std::__throw_bad_alloc();
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
}
が走る。つまり、俺の環境だと、std::vector<int> v(100);すると::operator new(std::size_t)が呼び出されて、例外機構を殺して確保も失敗するなら投げられたbad_alloc例外を処理できずにコケる。
これを書き換えてoperator new(__n * sizeof(_Tp), std::nothrow);とするならallocateはメモリを確保できない時にnullptrを返す。すると次に_M_default_initializeが走って、
最終的にplacement newが走って、thisをデレファレンスした瞬間にセグメンテーションフォールトでコケる。
要するに、例外が発生して安全に停止する前提でライブラリが組まれてるから、例外機能をオフにしたら不安定な動作になる。
例外機能をオフにしようが何しようがthrow自体は出来るので、きちんとcatchしましょうって話に落ち着くかと。

295:デフォルトの名無しさん
16/02/02 14:09:39.60 oBfAWjKR.net
>>288
知らなかった・・・

296:デフォルトの名無しさん
16/02/02 15:14:11.42 Ycdr5jOx.net
まあせいぜい「配列への参照」くらいまでだな。

297:デフォルトの名無しさん
16/02/02 15:35:32.57 TPiwOAfk.net
aが配列だったらint*の引数部分に&aの形でもいいのか
なんか気持ち悪いな

298:デフォルトの名無しさん
16/02/02 15:59:38.85 5quLb8ti.net
>>286
回答ありがとうございます。
protectedで継承しているのでstatic_castは無効なのです。
これは移植性ないとみるべきなんでしょうか。
強引にCスタイルキャストでごまかすべきか・・・。Orz

299:デフォルトの名無しさん
16/02/02 17:00:35.47 ucpE/ELv.net
>>282
細かいことを言うようだけど &a == &a[0] ではないよ。
下の例で、3つのprintf()は同じ値(アドレス)を表示する。
けれども if の部分で有効なのは最初の行だけ。
下の2つのif行の注釈を外すとコンパイルエラーになるはず。
a と &a[0] は等しい。
&a と &a[0] は(値は同じだが)型が違う。型が違うので比較はできない。

#include <cstdio>
int main() {
 int a[] = {1, 2, 3, 4};
 printf("a == %p\n", a);
 printf("&a[0] == %p\n", &a[0]);
 printf("&a == %p\n", &a);
 if (a == &a[0]) printf("Equal\n");
 // if (&a == &a[0]) printf("Equal\n");
 // if (a == &a) printf("Equal\n");
 return 0;
}

>>282 の本題、&a と &a[0] の値が同じになる理由は、
配列の中身がメモリにどう格納されるか、を図で表すと分かりやすいんだが
俺の表現力では無理なんでどなたか頼む。

300:デフォルトの名無しさん
16/02/02 17:01:52.82 7f7wf/mW.net
>>298
castして欲しくないからprotectedにしてるんじゃないの?

301:デフォルトの名無しさん
16/02/02 17:23:10.99 5quLb8ti.net
>>300
いやー、ハンドルみたいな使い方を規定していて、
自分は外部関数で値を変更したいんですけど、ユーザーには触ってほしくない。
という、わがままな欲求です。
そのうちUnified Call Syntaxが入ったら、いろいろやろうと思ってるところです。

302:デフォルトの名無しさん
16/02/02 17:25:43.26 MIlHcyxr.net
>>299
コレ昔VC6でやったら結果が違った
BCC5だとすべて同じ値なのに

303:デフォルトの名無しさん
16/02/02 17:29:56.27 MIlHcyxr.net
vc6だと&aが結局何処差し示しているかわからんかった

304:299
16/02/02 17:53:41.97 ucpE/ELv.net
>>302
a[] において &a が配列全体のアドレスを表すってのは
ANSI C で統一された挙動だったね。調べ直しちゃったよ。
C++ でも成立するよな。自信が揺らいできた。

305:デフォルトの名無しさん
16/02/02 17:55:25.15 C4M/U0aw.net
VCは規格準拠してないらしいからね
しかたないね

306:デフォルトの名無しさん
16/02/02 18:30:04.71 1NZHqYvt.net
>>282
たまたまお前の処理系がバイト単位でリニアアドレッシングしてるから。
int a[3]; について
 &a[0] は先頭要素のアドレス
 &a は「a[0] a[1] a[2]」という配列全体のアドレス
だから一致する

307:デフォルトの名無しさん
16/02/02 18:31:29.65 QW7JMPO0.net
>>282
URLリンク(ideone.com)
&a[0]は要素へのポインタ(一個目の要素へのポインタ)
&aは配列へのポインタ(一個目の配列へのポインタ)だよ
>>231
     :(~):
   :(i:i:i:i:i):
   :(i:i:i:i:i:i:i:):
  :( ゙´ω`゙):   …
  :(:::::::::ソ:::っ:
   :し─J ┃:

308:デフォルトの名無しさん
16/02/02 18:35:17.86 KYl+p0oO.net
一個目の配列って、日本語変

309:デフォルトの名無しさん
16/02/02 19:17:24.83 WSo7+ODL.net
&&&&****aとか&&&&aとかにしても通ってしまう気がした

310:デフォルトの名無しさん
16/02/02 20:12:44.79 po3vtalA.net
arrayと&array[0]が同じなら
なんでsizeof(array)で正しくサイズが出てくるのか分からん

311:デフォルトの名無しさん
16/02/02 20:35:13.03 WkrnCzmR.net
>>310
> arrayと&array[0]が同じなら
ポインタに変換したら一緒になると言うだけ
> なんでsizeof(array)で正しくサイズが出てくるのか分からん
array 自体のサイズをコンパイラは知ってるから

312:デフォルトの名無しさん
16/02/02 20:54:40.03 MIlHcyxr.net
>>309
&と&&は別物だよ
ちなみに&&は定数も代入できる

313:デフォルトの名無しさん
16/02/02 20:56:18.82 RveVHAYz.net
>>312
馬鹿は去れ

314:デフォルトの名無しさん
16/02/02 21:28:49.56 5quLb8ti.net
array[] -> 配列の型
array[0] ->配列の要素の型
sizeof(array)はdecltype(array)の暗黙に持ってる長さ情報にアクセスしている?
array == &array[0] はアドレス値は同じだが、型自体は違うので持ってる情報は違うもの。前者はT[]。後者は(&T)
暗黙の型変換でぐちゃぐちゃになってるのはお前の頭だ!
であってる?

315:デフォルトの名無しさん
16/02/02 21:29:30.66 5quLb8ti.net
T&か。

316:デフォルトの名無しさん
16/02/02 21:30:29.16 MIlHcyxr.net
int &&a = 5 ;

317:デフォルトの名無しさん
16/02/02 21:33:13.54 5quLb8ti.net
>>316
int&& a=int(5);と等価だっけ?

318:デフォルトの名無しさん
16/02/02 21:34:17.88 MIlHcyxr.net
T&&a=5 ; が a自体の参照で、
T&&a=n ; でnの参照になったりする。自動で。

319:デフォルトの名無しさん
16/02/02 21:34:40.95 06fZR6NS.net
const hoge h;
h.~hoge();
デストラクタはconstついてないのに呼べるのは何故ですか

320:デフォルトの名無しさん
16/02/02 21:53:06.16 RveVHAYz.net
>>302
今確認したが同じアドレスになった
どうしてそう息を吸って吐くように嘘をつくのか
ちなみに&aがどこを指しているかわからないのは
Visual C++ 6.0じゃなくてお前のオツムが原因

321:デフォルトの名無しさん
16/02/02 22:09:17.83 MIlHcyxr.net
>>320
Hotfixいれまくったりすると環境変わるからね
昔のことだからよく覚えてないけど

322:デフォルトの名無しさん
16/02/02 22:20:22.89 RveVHAYz.net
まあこのメッセージを読んでもどこ指してるかわからないようでは致し方ない
int *p = &a;
error C2440: 'initializing' : 'int (*)[4]' から 'int *' に変換することはできません。(新しい動作 ; ヘルプを参照)

323:デフォルトの名無しさん
16/02/02 22:51:04.27 MIlHcyxr.net
>>322
バカでもわかる型の違いですけど
なんでキャストしないのですか?

324:デフォルトの名無しさん
16/02/02 23:11:50.94 x5amnXbs.net
キャストで逃げようとするほうがバカ
なんで&a[0]にしないのですか?

325:デフォルトの名無しさん
16/02/02 23:20:08.01 RveVHAYz.net
知っててキャストするなら問題ないだろう
だが>>323の様にどこを指しているかわからないと言ってるのにキャストするのはヤバい
>>318とかはよ病院に行くレベル

326:デフォルトの名無しさん
16/02/02 23:20:42.79 x5amnXbs.net
(int*)a:7文字 static_castだと当然もっと長くなる
&a[0]:5文字

327:デフォルトの名無しさん
16/02/02 23:27:30.24 MIlHcyxr.net
何処もヤバくないと思うんだがね
病院逝くのは貴様の方だろ

328:デフォルトの名無しさん
16/02/02 23:31:01.70 7f7wf/mW.net
&*a:3文字

329:デフォルトの名無しさん
16/02/02 23:40:56.45 x5amnXbs.net
&a[0]ならaがstd::vector<int>になっても通用するからそう書けよこのスットコドッコイども

330:デフォルトの名無しさん
16/02/03 00:24:20.72 5VKefHqD.net
c++スレ名物の殴り合いが始まりました!

331:デフォルトの名無しさん
16/02/03 07:32:59.13 Gb259GwX.net
>>329
(int*)aって書ける時点でaは配列かポインタだろ
なんでvectorクラスを仮定してんだよ

332:デフォルトの名無しさん
16/02/03 12:46:03.59 6CbCMv4Y.net
URLリンク(ideone.com)
Javaとは違いC++は基底クラスのインスタンスを派生クラスにダウンキャスト出来てしまうのですが、
これは正しい挙動なのでしょうか。
またオーバーライドした関数が呼べるのは理解できるのですが、
派生クラス独自の関数も呼べてしまうのは腑に落ちません。

333:デフォルトの名無しさん
16/02/03 12:54:30.47 AVVts3m8.net
C++としては正しいが、当然危険なコードなので
もしそうせざるを得ない場合は、設計が間違ってると思うべき

334:デフォルトの名無しさん
16/02/03 12:59:18.19 AVVts3m8.net
正しい挙動の意味にもよるが
どうしても使わざるを得ない場合はdynamic_castを使うべき

335:デフォルトの名無しさん
16/02/03 13:02:03.09 EbXG9hpy.net
>>332
実行時のチェックなしでできてしまうって意味だよね?
プログラマが手動でメモリを割り付けてたりする場合もあるから、下手にチェックされても困るケースがある。
チェックしてほしければvirtual関数持たせた上でdynamic_castしろ。
あと、gが呼べるのは暗黙の引数であるthisに触ってないから、thisがなんであっても問題が表出しないだけ。

336:デフォルトの名無しさん
16/02/03 13:59:40.04 XI3wSbIf.net
>>332
C++言語の仕様上behavior is undefinedなので
どのような結果になっても正しいからな
コンパイラーの出力するコードの都合でたまたまエラー無くspecialが呼び出せてもおかしくはない

337:デフォルトの名無しさん
16/02/03 19:09:23.55 V5mcV8ll.net
私はこの分野にあまり詳しくはないのですが、そうなんですか?

338:デフォルトの名無しさん
16/02/03 19:56:03.11 5VKefHqD.net
>>331
えっ?!

339:デフォルトの名無しさん
16/02/03 23:17:57.39 XI3wSbIf.net
>>337
そうなんです
プログラマーは全知全能でミスをしたら自己責任という思想の言語なので
都合の悪いことはundefined behaviorの扱いにするのがC/C++のお家芸


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch