C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。
前スレ
C++相談室 part144
https://mevius.5ch.net/test/read.cgi/tech/1563769115/
このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.105【環境依存OK】
https://mevius.5ch.net/test/read.cgi/tech/1556142878/
■長いソースを貼るときはここへ。■
http://codepad.org/
https://ideone.com/
[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
----- テンプレ ここまで -----
探検
C++相談室 part145
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2019/09/13(金) 17:13:24.60ID:/ygW08Jq675デフォルトの名無しさん
2019/10/30(水) 09:45:24.54ID:vMK+Q7lg676デフォルトの名無しさん
2019/10/30(水) 11:38:54.67ID:M6J6raPE コンテナの場合はスタックに置いたつもりでも、コンテナがデータ部分を内部でnewするとかそういう話だろ
677はちみつ餃子 ◆8X2XSCHEME
2019/10/30(水) 12:07:14.45ID:qu4eF7c5 >>667-668
仕様上は配列の範囲外を指すポインタを作るのさえも未定義。
たとえアクセスしなくても。
なので、 ptr-1 という式の時点で未定義動作になる。
ただし、アクセスしないなら配列の最後の要素より一個うしろを指すポインタを作るのは許される。
つまりこの例で言えば ptr+2 や &ptr[2] は有りだけど ptr[2] は駄目。
&ptr[2] は ptr[2] に対して & を付けているので一見すると途中で ptr[2] を評価しているように見えるけど、
・ ptr[2] は (*(ptr+2)) の構文糖である
・ * の結果に & を適用している場合には * も & も評価されず、両方とも取り除いたのと同じことになる
というルールの合わせ技によって &ptr[2] は ptr+2 と同じ意味になる。
ちなみに、配列ではないオブジェクトは要素が一個の配列と同じレイアウトを持つことは保証される。
仕様上は配列の範囲外を指すポインタを作るのさえも未定義。
たとえアクセスしなくても。
なので、 ptr-1 という式の時点で未定義動作になる。
ただし、アクセスしないなら配列の最後の要素より一個うしろを指すポインタを作るのは許される。
つまりこの例で言えば ptr+2 や &ptr[2] は有りだけど ptr[2] は駄目。
&ptr[2] は ptr[2] に対して & を付けているので一見すると途中で ptr[2] を評価しているように見えるけど、
・ ptr[2] は (*(ptr+2)) の構文糖である
・ * の結果に & を適用している場合には * も & も評価されず、両方とも取り除いたのと同じことになる
というルールの合わせ技によって &ptr[2] は ptr+2 と同じ意味になる。
ちなみに、配列ではないオブジェクトは要素が一個の配列と同じレイアウトを持つことは保証される。
678デフォルトの名無しさん
2019/10/30(水) 12:14:10.66ID:pPHw66rS679デフォルトの名無しさん
2019/10/30(水) 12:21:16.92ID:C/RG5q83 >>677
>ちなみに、配列ではないオブジェクトは要素が一個の配列と同じレイアウトを持つこと>は保証される。
しかも、TYPE arr[N] の場合、それぞれの要素間隔であるところの
&arr[k] と &arr[k + 1] の差は、厳密に sizeof(TYPE)に一致する。
struct TXxx { BYTE a[3] }; のように中途半端な内容を持っている場合、
標準的には、sizeof(TXxx)は最後のpaddingまで含めた4になる。
その結果、古くからCの仕様書に載っている通り、
&arr[k] = (TYPE *)(((BYTE *)arr) + sizeof(TYPE) * k)
の式が常に厳密に成り立つことが保証される。
>ちなみに、配列ではないオブジェクトは要素が一個の配列と同じレイアウトを持つこと>は保証される。
しかも、TYPE arr[N] の場合、それぞれの要素間隔であるところの
&arr[k] と &arr[k + 1] の差は、厳密に sizeof(TYPE)に一致する。
struct TXxx { BYTE a[3] }; のように中途半端な内容を持っている場合、
標準的には、sizeof(TXxx)は最後のpaddingまで含めた4になる。
その結果、古くからCの仕様書に載っている通り、
&arr[k] = (TYPE *)(((BYTE *)arr) + sizeof(TYPE) * k)
の式が常に厳密に成り立つことが保証される。
680デフォルトの名無しさん
2019/10/30(水) 12:25:41.94ID:C/RG5q83 >>678
operator&(), operator*() をユーザーが定義した場合には、それに従うが、
定義しなかった場合、&*pX == pX が どんなポインタ pX についても
成り立つことは保証されるはず。
operator&(), operator*() をユーザーが定義した場合には、それに従うが、
定義しなかった場合、&*pX == pX が どんなポインタ pX についても
成り立つことは保証されるはず。
681デフォルトの名無しさん
2019/10/30(水) 13:28:14.72ID:JDSjHFuf >>670
一般的なPC環境なら、
適当に用意した別の関数を呼び出して(multi_arrayのインスタンスがまだ有効で、インスタンス生成したスレッドと同一スレッドからなら、どこから呼び出してもよい)、
その関数のローカル変数のアドレスよりも&multi_array[0]の値のほうが大きければ、multi_arrayのデータ領域はスタックに確保されたと判断できるのでは
一般的なPC環境なら、
適当に用意した別の関数を呼び出して(multi_arrayのインスタンスがまだ有効で、インスタンス生成したスレッドと同一スレッドからなら、どこから呼び出してもよい)、
その関数のローカル変数のアドレスよりも&multi_array[0]の値のほうが大きければ、multi_arrayのデータ領域はスタックに確保されたと判断できるのでは
682デフォルトの名無しさん
2019/10/30(水) 13:38:23.28ID:C/RG5q83 >>681
自分も最初、同じような勘違いをしていたが、
シングルスレッドの場合に限定すれば、
スタックの構造からすれば、最初に確保したローカル変数のアドレスが、
そのごろのローカル変数のアドレスよりも必ず大きい。
そして、ヒープから確保したオブジェクトのアドレスは、必ずそれらよりも大きい。
なので、後から別の関数を呼び出す必要はない。
main()関数の中で最初に定義したローカル変数のアドレスが分かればそれで十分。
自分も最初、同じような勘違いをしていたが、
シングルスレッドの場合に限定すれば、
スタックの構造からすれば、最初に確保したローカル変数のアドレスが、
そのごろのローカル変数のアドレスよりも必ず大きい。
そして、ヒープから確保したオブジェクトのアドレスは、必ずそれらよりも大きい。
なので、後から別の関数を呼び出す必要はない。
main()関数の中で最初に定義したローカル変数のアドレスが分かればそれで十分。
683デフォルトの名無しさん
2019/10/30(水) 13:39:27.23ID:C/RG5q83684デフォルトの名無しさん
2019/10/30(水) 16:43:27.90ID:iACLsVPd 0 埋め勝手に期待してると
Debug build と Release build の変化ではまるんじゃね
Debug build と Release build の変化ではまるんじゃね
685デフォルトの名無しさん
2019/10/30(水) 18:21:24.13ID:sLIKMMS8 未定義動作に頼って幸せになった人間はいない
686デフォルトの名無しさん
2019/10/30(水) 18:25:45.90ID:PFJwOjFS 問題は未定義動作が多すぎることだ
687デフォルトの名無しさん
2019/10/30(水) 19:14:52.52ID:NnKRxbK9688デフォルトの名無しさん
2019/10/30(水) 19:53:22.92ID:/8g3afGg c++なら暗黙に0で初期化するところでcだと死ぬ
689はちみつ餃子 ◆8X2XSCHEME
2019/10/30(水) 20:10:37.29ID:qu4eF7c5 Boehm GC にスタック・ヒープの範囲を判定する部分があったはず。
690デフォルトの名無しさん
2019/10/30(水) 20:42:33.17ID:MNbPntdA >>682
ヒープから確保したアドレスがスタックより大きいっていうのはかなり特殊な環境では?
ヒープから確保したアドレスがスタックより大きいっていうのはかなり特殊な環境では?
691デフォルトの名無しさん
2019/10/30(水) 20:46:40.08ID:7FaQcqiv692デフォルトの名無しさん
2019/10/30(水) 21:02:17.94ID:xN/ut28D お前ら甘いぞ
ヒープから確保したメモリをスタックにすることもできるんやで
逆にいうとスタックの情報もとれる
pthread_attr_getstackな
ヒープから確保したメモリをスタックにすることもできるんやで
逆にいうとスタックの情報もとれる
pthread_attr_getstackな
693デフォルトの名無しさん
2019/10/30(水) 21:28:56.04ID:KWwo/1iW https://ideone.com/Q4ek9R
デストラクタを後から書き換えるってできなかったっけ?
デストラクタを後から書き換えるってできなかったっけ?
694デフォルトの名無しさん
2019/10/30(水) 21:37:47.50ID:scNMtFri なんで出来ると思ったのか
695デフォルトの名無しさん
2019/10/30(水) 21:41:50.59ID:/8g3afGg おまえらはなんですぐ破壊的なメモリアクセスしようとするんだよ。
696デフォルトの名無しさん
2019/10/30(水) 21:44:55.49ID:KWwo/1iW697デフォルトの名無しさん
2019/10/30(水) 21:47:25.90ID:M6J6raPE 変にトリッキーなことをせず普通に書けば平和なのに
698デフォルトの名無しさん
2019/10/30(水) 21:51:21.63ID:Z1e8Gfkt 平和を求めるならc++使わないことだな
699デフォルトの名無しさん
2019/10/30(水) 21:56:38.45ID:Z1e8Gfkt >>696
virtualでないと子のデストラクタは呼ばれないってのとごっちゃになってるとか?
virtualでないと子のデストラクタは呼ばれないってのとごっちゃになってるとか?
700デフォルトの名無しさん
2019/10/30(水) 21:57:32.16ID:/8g3afGg >>698
平和は求めるが性能も求めるから仕方なく使うのがc++だよ、馬鹿。
平和は求めるが性能も求めるから仕方なく使うのがc++だよ、馬鹿。
701デフォルトの名無しさん
2019/10/30(水) 22:07:52.76ID:KWwo/1iW >>699
多分それだ。もやもや取れたわ。ありがとう。
多分それだ。もやもや取れたわ。ありがとう。
702デフォルトの名無しさん
2019/10/30(水) 22:15:48.21ID:Z1e8Gfkt >>700
お前moveだからコピーコストゼロ!カロリーゼロとか言ってるだろ
お前moveだからコピーコストゼロ!カロリーゼロとか言ってるだろ
703デフォルトの名無しさん
2019/10/30(水) 22:18:45.46ID:T2yRPHdv >>693
正直何をしたいのかさっぱりわからん
正直何をしたいのかさっぱりわからん
704デフォルトの名無しさん
2019/10/31(木) 00:30:04.67ID:Mfb82uAb >>687
なるほど、想定していたのは、Windows環境限定だった。
なるほど、想定していたのは、Windows環境限定だった。
705デフォルトの名無しさん
2019/10/31(木) 01:11:19.07ID:Z73hoFPo >>679
> &arr[k] と &arr[k + 1] の差は、厳密に sizeof(TYPE)に一致する。
いや、 &arr[k + 1] - &arr[k] は 1 でしょ。
> その結果、古くからCの仕様書に載っている通り、
> &arr[k] = (TYPE *)(((BYTE *)arr) + sizeof(TYPE) * k)
> の式が常に厳密に成り立つことが保証される。
少なくとも C++ の規格にもそんな保証は載ってないよ。
逆に、 TYPE が BYTE と一致するような場合を除いて、動作は未定義になると明記されてる。
https://timsong-cpp.github.io/cppwp/n4659/expr.add#6
たぶん C の規格にも無かったと思うんだけど、「Cの仕様書」って何のこと言ってるの?
>>680 も、規格で保証されると言ってるなら誤り。
特定の実装(特に C もサポートしてる実装)では保証されているとか、
保証されてないと困るという話ならそうなんだろうとは思うけど。
> &arr[k] と &arr[k + 1] の差は、厳密に sizeof(TYPE)に一致する。
いや、 &arr[k + 1] - &arr[k] は 1 でしょ。
> その結果、古くからCの仕様書に載っている通り、
> &arr[k] = (TYPE *)(((BYTE *)arr) + sizeof(TYPE) * k)
> の式が常に厳密に成り立つことが保証される。
少なくとも C++ の規格にもそんな保証は載ってないよ。
逆に、 TYPE が BYTE と一致するような場合を除いて、動作は未定義になると明記されてる。
https://timsong-cpp.github.io/cppwp/n4659/expr.add#6
たぶん C の規格にも無かったと思うんだけど、「Cの仕様書」って何のこと言ってるの?
>>680 も、規格で保証されると言ってるなら誤り。
特定の実装(特に C もサポートしてる実装)では保証されているとか、
保証されてないと困るという話ならそうなんだろうとは思うけど。
706デフォルトの名無しさん
2019/10/31(木) 07:54:20.46ID:CWgnmwch 保証は知らんけどアドレス計算だから1じゃなくてsizeofの値じゃないのそれ
あとだめならベクタで&v[x]みたいのも未定義になっちゃうけども
あとだめならベクタで&v[x]みたいのも未定義になっちゃうけども
707はちみつ餃子 ◆8X2XSCHEME
2019/10/31(木) 12:29:41.78ID:/W+zTx1p >>705
俺も仕様としての保証はないと思う。
C の規格を見て関連しそうな項目として
- ポインタを型変換して変換後のアライン (処理系定義) が正しければそれを元の型に再変換したものは変換前と等しい
- ポインタを別のポインタに型変換した後のアラインが正しくなければ未定義
- ポインタを文字を指すポインタに型変換した場合、オブジェクトの最も低位のアドレスを指す
- 文字を指すポインタに変換されたポインタは元のオブジェクトの大きさまで連続して増分すると
そのオブジェクトの残りのバイトへのポインタを順次生成できる
(注:ここで言うポインタには関数ポインタを含まない)
という保証は見つけられたので
(((BYTE *)arr) + sizeof(TYPE) * k)
までは妥当な式と言えると思うんだけど、 (TYPE *) というキャストが出来る根拠は見つけられなかった。
俺も仕様としての保証はないと思う。
C の規格を見て関連しそうな項目として
- ポインタを型変換して変換後のアライン (処理系定義) が正しければそれを元の型に再変換したものは変換前と等しい
- ポインタを別のポインタに型変換した後のアラインが正しくなければ未定義
- ポインタを文字を指すポインタに型変換した場合、オブジェクトの最も低位のアドレスを指す
- 文字を指すポインタに変換されたポインタは元のオブジェクトの大きさまで連続して増分すると
そのオブジェクトの残りのバイトへのポインタを順次生成できる
(注:ここで言うポインタには関数ポインタを含まない)
という保証は見つけられたので
(((BYTE *)arr) + sizeof(TYPE) * k)
までは妥当な式と言えると思うんだけど、 (TYPE *) というキャストが出来る根拠は見つけられなかった。
708デフォルトの名無しさん
2019/10/31(木) 13:00:56.65ID:Mfb82uAb709デフォルトの名無しさん
2019/10/31(木) 13:06:36.29ID:iFqs222y ×基礎
○妄想の中の理想世界・ご都合ワールド
○妄想の中の理想世界・ご都合ワールド
710デフォルトの名無しさん
2019/10/31(木) 13:21:36.49ID:Mfb82uAb https://en.cppreference.com/w/c/language/sizeof
1. sizeof( type ) Returns the size, in bytes, of the object representation of type
2. When applied to an operand that has structure or union type,
the result is the total number of bytes in such an object, including
internal and trailing padding. The trailing padding is such that
if the object were an element of an array, the alignment requirement
of the next element of this array would be satisfied, in other words,
sizeof(T) returns the size of an element of a T[] array.
3. Number of elements in any array a including VLA (since C99) may be
determined with the expression sizeof a / sizeof a[0]. Note that
if a has pointer type (such as after array-to-pointer conversion of
function parameter type adjustment), this expression would simply
divide the number of bytes in a pointer type by the number of bytes
in the pointed type.
https://en.cppreference.com/w/c/language/operator_arithmetic
10. If the pointer P points at an element of an array with index I, then
11. P+N and N+P are pointers that point at an element of the same array with index I+N.
12. P-N is a pointer that points at an element of the same array with index {tt|I-N}}.
20. If the pointer P1 points at an element of an array with index I (or one past the end)
and P2 points at an element of the same array with index J (or one past the end), then
P1-P2 has the value equal to J-I and the type ptrdiff_t (which is a signed integer type,
typically half as large as the size of the largest object that can be declared)
1. sizeof( type ) Returns the size, in bytes, of the object representation of type
2. When applied to an operand that has structure or union type,
the result is the total number of bytes in such an object, including
internal and trailing padding. The trailing padding is such that
if the object were an element of an array, the alignment requirement
of the next element of this array would be satisfied, in other words,
sizeof(T) returns the size of an element of a T[] array.
3. Number of elements in any array a including VLA (since C99) may be
determined with the expression sizeof a / sizeof a[0]. Note that
if a has pointer type (such as after array-to-pointer conversion of
function parameter type adjustment), this expression would simply
divide the number of bytes in a pointer type by the number of bytes
in the pointed type.
https://en.cppreference.com/w/c/language/operator_arithmetic
10. If the pointer P points at an element of an array with index I, then
11. P+N and N+P are pointers that point at an element of the same array with index I+N.
12. P-N is a pointer that points at an element of the same array with index {tt|I-N}}.
20. If the pointer P1 points at an element of an array with index I (or one past the end)
and P2 points at an element of the same array with index J (or one past the end), then
P1-P2 has the value equal to J-I and the type ptrdiff_t (which is a signed integer type,
typically half as large as the size of the largest object that can be declared)
711デフォルトの名無しさん
2019/10/31(木) 13:43:36.78ID:hGg8JwcT C++のヘッダファイルのクラス定義って、
privateまで定義しないといかんのが嫌だな。
privateだから内部に隠蔽されて、外部からは知らなくていい情報なのに
内部で使ってる型をヘッダファイルに書かなければいけないから、
それをincludeしてる方も、その型の存在を知ってしまう。
どうにかならんのかな?
privateまで定義しないといかんのが嫌だな。
privateだから内部に隠蔽されて、外部からは知らなくていい情報なのに
内部で使ってる型をヘッダファイルに書かなければいけないから、
それをincludeしてる方も、その型の存在を知ってしまう。
どうにかならんのかな?
712デフォルトの名無しさん
2019/10/31(木) 13:54:48.05ID:Nmr38VJU ヘッダに描くのをやめればいい
713デフォルトの名無しさん
2019/10/31(木) 14:01:21.28ID:Mfb82uAb >>710
「1.」によれば、sizeof(x)は、xのバイトサイズである。
「2.] によれば、xが構造体の場合、sizeof(x)には、構造体のメンバの間や
最後のpaddingのサイズまで含まれている。
「3.」によれば、TYPE a[N]; の場合、sizeof(a)/sizeof(a[0]) == N
が保証されている。a[0] の型は TYPE なので、これは、
sizeof(a)/sizeof(TYPE) == N
であることを示す。sizeof(a)とは、配列型a全体のサイズであるので、
これはつまり、a[k] のアドレスが、(a[0] のアドレス) + sizeof(TYPE) * k
であることを意味している。
よって、>>708 は正しい。
「1.」によれば、sizeof(x)は、xのバイトサイズである。
「2.] によれば、xが構造体の場合、sizeof(x)には、構造体のメンバの間や
最後のpaddingのサイズまで含まれている。
「3.」によれば、TYPE a[N]; の場合、sizeof(a)/sizeof(a[0]) == N
が保証されている。a[0] の型は TYPE なので、これは、
sizeof(a)/sizeof(TYPE) == N
であることを示す。sizeof(a)とは、配列型a全体のサイズであるので、
これはつまり、a[k] のアドレスが、(a[0] のアドレス) + sizeof(TYPE) * k
であることを意味している。
よって、>>708 は正しい。
714デフォルトの名無しさん
2019/10/31(木) 14:04:09.17ID:/uM4xbrd >>711
pimpl
pimpl
715デフォルトの名無しさん
2019/10/31(木) 14:46:45.02ID:Mfb82uAb >>705
>> &arr[k] と &arr[k + 1] の差は、厳密に sizeof(TYPE)に一致する。
>いや、 &arr[k + 1] - &arr[k] は 1 でしょ。
この場合の「差」とは、減算演算子 x - y の結果のことではなく、
アドレスの差のことです。丁寧に書けば、
「&arr[k] のアドレス値と &arr[k + 1] のアドレス値の差は、厳密に sizeof(TYPE)
に一致する。」または、
「arr[k] のアドレスと arr[k + 1] のアドレスの差は、厳密に sizeof(TYPE)
に一致する。」
となります。
>> &arr[k] と &arr[k + 1] の差は、厳密に sizeof(TYPE)に一致する。
>いや、 &arr[k + 1] - &arr[k] は 1 でしょ。
この場合の「差」とは、減算演算子 x - y の結果のことではなく、
アドレスの差のことです。丁寧に書けば、
「&arr[k] のアドレス値と &arr[k + 1] のアドレス値の差は、厳密に sizeof(TYPE)
に一致する。」または、
「arr[k] のアドレスと arr[k + 1] のアドレスの差は、厳密に sizeof(TYPE)
に一致する。」
となります。
716デフォルトの名無しさん
2019/10/31(木) 14:50:36.73ID:Mfb82uAb >>691
言語仕様的には決まっていませんが、Win32で実験する場合、
最初の質問者が、答えを見つける手段としては、正しいやり方なのです。
Win32で実験してヒープからの確保なのかどうか判明してしまえば、同じ
boostのソースを他の環境で動かしても、#ifdef などで動作が変えられていない
限りは、同じ結果となるからです。
言語仕様的には決まっていませんが、Win32で実験する場合、
最初の質問者が、答えを見つける手段としては、正しいやり方なのです。
Win32で実験してヒープからの確保なのかどうか判明してしまえば、同じ
boostのソースを他の環境で動かしても、#ifdef などで動作が変えられていない
限りは、同じ結果となるからです。
717はちみつ餃子 ◆8X2XSCHEME
2019/10/31(木) 14:53:56.72ID:/W+zTx1p >>713
アドレスがどうこうじゃなくてキャストが許されるかっていう話なんだけど。
アドレスがどうこうじゃなくてキャストが許されるかっていう話なんだけど。
718デフォルトの名無しさん
2019/10/31(木) 15:27:23.28ID:CWgnmwch ポインタのキャストてポインタが指してるアドレスのデータの解釈だけの問題だから許されないキャストがそもそもないのでは
適切かどうかは知ったことではないが
というか配列のデータが連続していれば当然のごとく成り立つ話じゃん
それは保証されてるわけだし
適切かどうかは知ったことではないが
というか配列のデータが連続していれば当然のごとく成り立つ話じゃん
それは保証されてるわけだし
719デフォルトの名無しさん
2019/10/31(木) 16:06:33.06ID:hGg8JwcT720デフォルトの名無しさん
2019/10/31(木) 16:29:14.27ID:Mfb82uAb >>718
構造体型へのポインタ同士については、単なる解釈し直しではなく、
アドレスの加減算を伴うことがあります。
しかし、BYTE型へのポインタから構造体型へのポインタへのキャストに
ついては、解釈のし直ししか、コンパイルのしようがなく、その場合に
ついては、ポインタの指すオブジェクトがマシン後レベルで同じアドレス
を持つことになります。ただし、厳密な仕様は知りません。
構造体型へのポインタ同士については、単なる解釈し直しではなく、
アドレスの加減算を伴うことがあります。
しかし、BYTE型へのポインタから構造体型へのポインタへのキャストに
ついては、解釈のし直ししか、コンパイルのしようがなく、その場合に
ついては、ポインタの指すオブジェクトがマシン後レベルで同じアドレス
を持つことになります。ただし、厳密な仕様は知りません。
721はちみつ餃子 ◆8X2XSCHEME
2019/10/31(木) 16:32:02.98ID:/W+zTx1p pimpl ってプライベートなメンバを隠したいだけのために導入するのは面倒くさ過ぎない?
手間かけてでもやりたいって場面もあるのかもしれんが、どうにも割に合う気がしない。
手間かけてでもやりたいって場面もあるのかもしれんが、どうにも割に合う気がしない。
722デフォルトの名無しさん
2019/10/31(木) 17:07:47.69ID:NdDnFbFX どうしても実装を隠さないと発狂する人が使う
723デフォルトの名無しさん
2019/10/31(木) 17:11:39.47ID:M7zdaumA unique_ptrで作ればそれだけで勝手にmovableなクラスになって便利だよpimpl
724デフォルトの名無しさん
2019/10/31(木) 17:17:39.90ID:hGg8JwcT >>721
プライベートなメンバを隠すと言うよりも
依存関係を断ち切らせたかった。
hoge.h と hoge.cpp があって、
hoge.cpp から #include<hoge.h> してる
main.cpp があってHogeクラスを使うから、#include<hoge.h> してる。
この時、mainは、Hogeクラスだけを使ってることにしたい。
でも、hoge.cpp は private で Hage func(); メソッドを定義してる。
つまり hoge.cpp は #include<hage.h> をしている。
そうすると,mainは、Hogeクラスだけ使うつもりなのに
間接的に hage.h もインクルードしてしまって、Hageクラスのこと知ってることになる。
Hogeを知るとHageも知ってしまう
Hageを隠したかったんだよ!
↑
言いたかったことはこれ
プライベートなメンバを隠すと言うよりも
依存関係を断ち切らせたかった。
hoge.h と hoge.cpp があって、
hoge.cpp から #include<hoge.h> してる
main.cpp があってHogeクラスを使うから、#include<hoge.h> してる。
この時、mainは、Hogeクラスだけを使ってることにしたい。
でも、hoge.cpp は private で Hage func(); メソッドを定義してる。
つまり hoge.cpp は #include<hage.h> をしている。
そうすると,mainは、Hogeクラスだけ使うつもりなのに
間接的に hage.h もインクルードしてしまって、Hageクラスのこと知ってることになる。
Hogeを知るとHageも知ってしまう
Hageを隠したかったんだよ!
↑
言いたかったことはこれ
725デフォルトの名無しさん
2019/10/31(木) 17:29:24.06ID:Mfb82uAb >>724
また髪の毛の話してる、などというと荒れそうなので決して言いません。
また髪の毛の話してる、などというと荒れそうなので決して言いません。
726はちみつ餃子 ◆8X2XSCHEME
2019/10/31(木) 17:52:49.82ID:/W+zTx1p C++20 でモジュールの機能が入るとかいう話になってるから
それが成れば pimpl なんていらんようになると思うんだが、
実際のところモジュールの様子ってどうなの?ちゃんと入りそう?
それが成れば pimpl なんていらんようになると思うんだが、
実際のところモジュールの様子ってどうなの?ちゃんと入りそう?
727デフォルトの名無しさん
2019/10/31(木) 18:23:02.02ID:ZttcTVl1 無理。
テンプレートとの両立、オーバーヘッドの問題
どの視点でみてもくそなものしかできないことは明白。
こういうのに引っかかるバカが増えたよね。
テンプレートとの両立、オーバーヘッドの問題
どの視点でみてもくそなものしかできないことは明白。
こういうのに引っかかるバカが増えたよね。
728デフォルトの名無しさん
2019/10/31(木) 18:32:01.00ID:gpc+5FVL >>721
そう思うのは複数人で規模のでかいもの作ってないから
そう思うのは複数人で規模のでかいもの作ってないから
729デフォルトの名無しさん
2019/10/31(木) 19:37:56.00ID:/uM4xbrd pimplは開発規模は関係なくて、ライブラリの公開するヘッダでユーザーに関係ないものを隠すために使わないか?
730はちみつ餃子 ◆8X2XSCHEME
2019/10/31(木) 20:03:49.64ID:/W+zTx1p731デフォルトの名無しさん
2019/10/31(木) 20:09:29.87ID:jES25g+p 個人的には、自分ひとりで作ってるプログラムは、高頻度で全ビルドに
かける癖が付いてしまってる。
こうしておくと、OSをSleepモードにしていて、誤って電源を切ってしまったような
時にIDEが管理しているプロジェクトのデータファイルの何かが壊れていても
気付なかった時や、プロジェクトのバックアップ処理の時のコピー操作の何らか
の間違いで何かがおかしくなってしまったようなときに変な不具合に悩まされなく
て済む。
かける癖が付いてしまってる。
こうしておくと、OSをSleepモードにしていて、誤って電源を切ってしまったような
時にIDEが管理しているプロジェクトのデータファイルの何かが壊れていても
気付なかった時や、プロジェクトのバックアップ処理の時のコピー操作の何らか
の間違いで何かがおかしくなってしまったようなときに変な不具合に悩まされなく
て済む。
732デフォルトの名無しさん
2019/10/31(木) 22:29:01.40ID:GkSnEle2 C++とオブジェクト指向をきちんと身につけてる人ばかりの環境ならいいんだけどね、pimpl
経験不足な人だと理解出来なさそう
経験不足な人だと理解出来なさそう
733デフォルトの名無しさん
2019/10/31(木) 22:54:10.87ID:/p/NkBNt 使ってるうちにインターフェースを使った典型的な奴とそう変わらない事に気付く
734デフォルトの名無しさん
2019/10/31(木) 22:58:21.62ID:KjvgkRuG 継承使いたくないからpimplの方が好き
735デフォルトの名無しさん
2019/10/31(木) 23:14:49.56ID:FGj4X+XO cpprefjpのサンプルの赤字の部分使い方合ってる?
https://cpprefjp.github.io/reference/memory/allocator_traits/select_on_container_copy_construction.html
https://cpprefjp.github.io/reference/memory/allocator_traits/select_on_container_copy_construction.html
736デフォルトの名無しさん
2019/10/31(木) 23:43:47.06ID:/p/NkBNt 確かに、select_on_container_copy_construction(other.alloc_)が正しいような気はする
737デフォルトの名無しさん
2019/11/01(金) 00:03:47.15ID:8rUFWNXZ テンプレート活用のための最適化が全盛期の今 pimpl は時代遅れ。
738デフォルトの名無しさん
2019/11/01(金) 00:09:16.78ID:rKg4WNgJ はいはい
739デフォルトの名無しさん
2019/11/01(金) 00:19:47.84ID:TUcr0tQH pimplが時代遅れというのなら、それに代わる
依存する必要がない所を断ち切る方法を提示してくれ
依存する必要がない所を断ち切る方法を提示してくれ
740デフォルトの名無しさん
2019/11/01(金) 00:24:57.04ID:8rUFWNXZ741デフォルトの名無しさん
2019/11/01(金) 01:06:00.24ID:pNQbmHLO >>739
インターフェースと継承
インターフェースと継承
742デフォルトの名無しさん
2019/11/01(金) 03:35:55.36ID:TUcr0tQH >>740-741
どちらも型を書くので依存を断ち切れてない
どちらも型を書くので依存を断ち切れてない
743デフォルトの名無しさん
2019/11/01(金) 05:46:43.28ID:xzGeRMKo pimplでも型を書くのに、何を言っているんだか
そんなに型を書くのが嫌なら、Cの不透明型でも使ってろ
そんなに型を書くのが嫌なら、Cの不透明型でも使ってろ
744デフォルトの名無しさん
2019/11/01(金) 06:27:26.52ID:62eq0k7o pimplの目的も方法も全く理解してないって白状したぞこいつ
745デフォルトの名無しさん
2019/11/01(金) 06:54:21.26ID:vkO9vKkI >>739
目の前のパソコンを窓から投げ捨てます
目の前のパソコンを窓から投げ捨てます
746デフォルトの名無しさん
2019/11/01(金) 07:17:25.47ID:luUnrp0t privateをどうしても隠蔽したいならpimpl使うのもやむを得ないのかも知らんけど、そんな事態になったこと無いからよくわからんな
747デフォルトの名無しさん
2019/11/01(金) 07:43:37.38ID:62eq0k7o ライブラリ作る時にstd::unordered_mapとかメンバに使いたいと思わないもんなのか、よくわからんな
pimplで.cppに閉じ込めないとコンパイラやSTLのバージョン違いで壊れるんだけど
pimplで.cppに閉じ込めないとコンパイラやSTLのバージョン違いで壊れるんだけど
748デフォルトの名無しさん
2019/11/01(金) 07:44:21.36ID:nMXewbQV >>739
自部屋に引き籠もって外界との依存を断ち切ります。
自部屋に引き籠もって外界との依存を断ち切ります。
749デフォルトの名無しさん
2019/11/01(金) 07:58:26.02ID:OvwU0XDV ライセンスに書いとけば良い
・プライベートは見ないで下さい。お触り禁止。
・プライベートは見ないで下さい。お触り禁止。
750デフォルトの名無しさん
2019/11/01(金) 08:11:36.17ID:s5avmMq4 ただ単に仕様と実装をすっきり分離できるというだけでも充分な動機になる
751デフォルトの名無しさん
2019/11/01(金) 08:20:42.72ID:luUnrp0t752デフォルトの名無しさん
2019/11/01(金) 08:22:07.06ID:luUnrp0t753デフォルトの名無しさん
2019/11/01(金) 08:25:35.79ID:StFJ+6Yp エディタが貧弱だったころの名残を未だに引き摺っている
仕様と実装を分離したらそれだけでファイルが倍に増えて管理が面倒になる
仕様はソースコードから逐次自動生成すればいい
なので昨今の言語はIDEに迎合していて、暗黙の大前提でIDEでの運用が見込まれている
それ単体で成り立つものでは無くなっている
仕様と実装を分離したらそれだけでファイルが倍に増えて管理が面倒になる
仕様はソースコードから逐次自動生成すればいい
なので昨今の言語はIDEに迎合していて、暗黙の大前提でIDEでの運用が見込まれている
それ単体で成り立つものでは無くなっている
754デフォルトの名無しさん
2019/11/01(金) 09:01:23.35ID:DyENPU43 因果関係を理解できない人ってプログラマ向いてない
755デフォルトの名無しさん
2019/11/01(金) 09:41:29.48ID:Oq+eTBHB class Util() {
public:
int aaa();
std::string bbb();
private:
MinorClass mc;
MinorClass mc zzz();
}
こういうユーティリティクラスがあって便利だなーって思ったときに、
便利だと思うのはaaaメソッドとかbbbメソッドであって
内部で使ってるMinorClassとかどうでもいいねん
Utilクラスのインクルードファイルはインクルードしたいけど
MinorClassのインクルードファイルはインクルードしたくないねん
そんなもんインクルードしたらMinorClassが変更になっただけで
Utilクラス使ってるところも変更になるやろ?
public:
int aaa();
std::string bbb();
private:
MinorClass mc;
MinorClass mc zzz();
}
こういうユーティリティクラスがあって便利だなーって思ったときに、
便利だと思うのはaaaメソッドとかbbbメソッドであって
内部で使ってるMinorClassとかどうでもいいねん
Utilクラスのインクルードファイルはインクルードしたいけど
MinorClassのインクルードファイルはインクルードしたくないねん
そんなもんインクルードしたらMinorClassが変更になっただけで
Utilクラス使ってるところも変更になるやろ?
756はちみつ餃子 ◆8X2XSCHEME
2019/11/01(金) 10:06:12.42ID:ichmHmwx >>755
そこをわからんって言ってるやついないんだよ。
わかった上で変更になったらどんくらい問題なんや? 別にええやろ。 と言う場面の方が多いという話なんだよ。
pimpl が有用な場面があるっていう主張もわかるよ。 わかるけど、そういう場面に遭遇したことないなぁという話なんだよ。
そこをわからんって言ってるやついないんだよ。
わかった上で変更になったらどんくらい問題なんや? 別にええやろ。 と言う場面の方が多いという話なんだよ。
pimpl が有用な場面があるっていう主張もわかるよ。 わかるけど、そういう場面に遭遇したことないなぁという話なんだよ。
757デフォルトの名無しさん
2019/11/01(金) 10:29:23.31ID:9RAuu3bH >>755
それだけならMinorClassを前方宣言するだけでincludeいらない
それだけならMinorClassを前方宣言するだけでincludeいらない
758デフォルトの名無しさん
2019/11/01(金) 10:32:58.37ID:XsK+HhVl759デフォルトの名無しさん
2019/11/01(金) 10:33:41.18ID:o99mOnqi Utilはあるライブラリの公開クラスです
MinorClassは標準ライブラリのテンプレートクラス(例えばstd::unordered_map<Hoge>)です
Aさんはとあるコンパイラver1.0でコンパイルしたライブラリのバイナリとヘッダーを配布しました(ソースは配ってない)
10年後にBさんがこのライブラリのバイナリを入手して使おうと思いました
その間にコンパイラの標準ライブラリも劇的な進化を遂げ、コンテナの内部構造に大幅な改良を加えて超高速化したと宣伝していました
Bさんはヘッダーをincludeしてコンパイラver8.0でビルドしました
さーて何が起こる?Utilがpimplだとどうなる?よくよく考えよう
MinorClassは標準ライブラリのテンプレートクラス(例えばstd::unordered_map<Hoge>)です
Aさんはとあるコンパイラver1.0でコンパイルしたライブラリのバイナリとヘッダーを配布しました(ソースは配ってない)
10年後にBさんがこのライブラリのバイナリを入手して使おうと思いました
その間にコンパイラの標準ライブラリも劇的な進化を遂げ、コンテナの内部構造に大幅な改良を加えて超高速化したと宣伝していました
Bさんはヘッダーをincludeしてコンパイラver8.0でビルドしました
さーて何が起こる?Utilがpimplだとどうなる?よくよく考えよう
760デフォルトの名無しさん
2019/11/01(金) 10:43:47.44ID:9RAuu3bH761デフォルトの名無しさん
2019/11/01(金) 11:01:10.12ID:XsK+HhVl privateメンバをポインタ型にする手間や不都合とpImplの手間や管理コストのどっちを取るかだろうな
基本的には継承するクラス以外のincludeは排除できる
ヘッダ内部での外部ライブラリのincludeは可能な限り避けるべき
基本的には継承するクラス以外のincludeは排除できる
ヘッダ内部での外部ライブラリのincludeは可能な限り避けるべき
762はちみつ餃子 ◆8X2XSCHEME
2019/11/01(金) 11:10:39.87ID:ichmHmwx763はちみつ餃子 ◆8X2XSCHEME
2019/11/01(金) 11:11:24.16ID:ichmHmwx764デフォルトの名無しさん
2019/11/01(金) 13:00:57.84ID:aQLx28Zt765はちみつ餃子 ◆8X2XSCHEME
2019/11/01(金) 13:23:21.41ID:ichmHmwx >>764
俺がしたことないという経験談だが、
ここで pimpl が割に合わないと出ている意見は
そういう状況があんまりないという内容だということの説明でもある。
そういう状況で必要だってのはわかってるし、
そういう状況にあるなら使えばいいよ。
それはわかってるんだよ。
だからしつこく説明しないいよっていう話。
俺がしたことないという経験談だが、
ここで pimpl が割に合わないと出ている意見は
そういう状況があんまりないという内容だということの説明でもある。
そういう状況で必要だってのはわかってるし、
そういう状況にあるなら使えばいいよ。
それはわかってるんだよ。
だからしつこく説明しないいよっていう話。
767デフォルトの名無しさん
2019/11/01(金) 14:32:22.73ID:o99mOnqi 単機能ライブラリ作って渡す仕事してる人にとっては日常なんで、検討外れとか抜かされても勝手なこと言ってんなあとしか
まあ、OSSしかやらないとか、最終の実行バイナリしか作らないとか、そもそも個人プレーで人にプログラム成果物渡したりしないとかなら、
pimplの価値わからんという気持ちになるのはしょうがないし、それが世界の全てだと思っちゃうのかもな
まあ、OSSしかやらないとか、最終の実行バイナリしか作らないとか、そもそも個人プレーで人にプログラム成果物渡したりしないとかなら、
pimplの価値わからんという気持ちになるのはしょうがないし、それが世界の全てだと思っちゃうのかもな
768はちみつ餃子 ◆8X2XSCHEME
2019/11/01(金) 14:59:10.92ID:ichmHmwx769はちみつ餃子 ◆8X2XSCHEME
2019/11/01(金) 15:01:01.21ID:ichmHmwx いる場所ではいるし、いらない場所ではいらないという当たり前のことしか言ってないつもりなんだけど。
770デフォルトの名無しさん
2019/11/01(金) 15:04:22.58ID:E92xj2lK 全員知らないことの方が多いのに相手が自分の分野のことを知らないと無知扱いするのは草生える
771デフォルトの名無しさん
2019/11/01(金) 16:16:45.44ID:luUnrp0t772デフォルトの名無しさん
2019/11/01(金) 18:28:24.75ID:5daK08GN 動的リンクなら古いコンパイラでコンパイルしたライブラリが使えるかどうかはOSの互換性次第だろ
773デフォルトの名無しさん
2019/11/01(金) 18:36:37.94ID:VMz8o48U774デフォルトの名無しさん
2019/11/01(金) 18:38:39.54ID:OIX3BcSW あぁ、メモリーレイアウトでずっこけるやつか。
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 中国外務省局長 「ポケットに手を入れていたのは寒いから」 日本との局長級会談で [お断り★]
- 【速報】中国外務省報道官 高市首相発言撤回なければ「断固たる対抗措置」 ★3 [蚤の市★]
- 高市首相答弁を“引き出した”立民・岡田克也氏が改めて説明「なぜ慎重な答弁をされなかったのか。非常に残念に思っている」 ★7 [ぐれ★]
- 中国、日本行き“50万人”キャンセル 渡航自粛でコロナ禍以来最大 ★3 [お断り★]
- 【国際】ロシアはすでに戦争準備段階――ポーランド軍トップが警告 [ぐれ★]
- 【速報】日本産牛肉の対中国輸出再開協議が中止 ★2 [おっさん友の会★]
- 【実況】博衣こよりのえちえちフログロ学力テスト🧪★4
- 【実況】博衣こよりのえちえちフログロ学力テスト🧪★3
- 【高市早苗】習近平、本気で激おこ [115996789]
- 【高市有事】高市早苗が就任一ヶ月でやったこと一覧wwwwwwwwwwwwwww [603416639]
- 【有事】高市、🥺麻生太郎に言わされただけだった。悲しいお人形やね…😢 [153490809]
- 高市早苗「中国が戦艦を使ったら存立危機事態」佐藤優氏「戦艦なんて時代遅れの艦船を持ってる訳ねーだろ」 [931948549]
