C++相談室 part145

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2019/09/13(金) 17:13:24.60ID:/ygW08Jq
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/ (日本語)

----- テンプレ ここまで -----
740デフォルトの名無しさん
垢版 |
2019/11/01(金) 00:24:57.04ID:8rUFWNXZ
>>739
クラスの前方宣言。
テンプレートによるコンパイルエラー回避。
2019/11/01(金) 01:06:00.24ID:pNQbmHLO
>>739
インターフェースと継承
2019/11/01(金) 03:35:55.36ID:TUcr0tQH
>>740-741
どちらも型を書くので依存を断ち切れてない
2019/11/01(金) 05:46:43.28ID:xzGeRMKo
pimplでも型を書くのに、何を言っているんだか
そんなに型を書くのが嫌なら、Cの不透明型でも使ってろ
2019/11/01(金) 06:27:26.52ID:62eq0k7o
pimplの目的も方法も全く理解してないって白状したぞこいつ
2019/11/01(金) 06:54:21.26ID:vkO9vKkI
>>739
目の前のパソコンを窓から投げ捨てます
2019/11/01(金) 07:17:25.47ID:luUnrp0t
privateをどうしても隠蔽したいならpimpl使うのもやむを得ないのかも知らんけど、そんな事態になったこと無いからよくわからんな
2019/11/01(金) 07:43:37.38ID:62eq0k7o
ライブラリ作る時にstd::unordered_mapとかメンバに使いたいと思わないもんなのか、よくわからんな
pimplで.cppに閉じ込めないとコンパイラやSTLのバージョン違いで壊れるんだけど
2019/11/01(金) 07:44:21.36ID:nMXewbQV
>>739
自部屋に引き籠もって外界との依存を断ち切ります。
2019/11/01(金) 07:58:26.02ID:OvwU0XDV
ライセンスに書いとけば良い
・プライベートは見ないで下さい。お触り禁止。
2019/11/01(金) 08:11:36.17ID:s5avmMq4
ただ単に仕様と実装をすっきり分離できるというだけでも充分な動機になる
2019/11/01(金) 08:20:42.72ID:luUnrp0t
>>747
> pimplで.cppに閉じ込めないとコンパイラやSTLのバージョン違いで壊れるんだけど
ん?どう言うこと?
なんかやり方間違えてね?
2019/11/01(金) 08:22:07.06ID:luUnrp0t
>>750
private部分を見なきゃいいだけだろw
そもそも実装は.cppに書くんだし
2019/11/01(金) 08:25:35.79ID:StFJ+6Yp
エディタが貧弱だったころの名残を未だに引き摺っている
仕様と実装を分離したらそれだけでファイルが倍に増えて管理が面倒になる
仕様はソースコードから逐次自動生成すればいい
なので昨今の言語はIDEに迎合していて、暗黙の大前提でIDEでの運用が見込まれている
それ単体で成り立つものでは無くなっている
2019/11/01(金) 09:01:23.35ID:DyENPU43
因果関係を理解できない人ってプログラマ向いてない
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クラス使ってるところも変更になるやろ?
2019/11/01(金) 10:06:12.42ID:ichmHmwx
>>755
そこをわからんって言ってるやついないんだよ。
わかった上で変更になったらどんくらい問題なんや? 別にええやろ。 と言う場面の方が多いという話なんだよ。
pimpl が有用な場面があるっていう主張もわかるよ。 わかるけど、そういう場面に遭遇したことないなぁという話なんだよ。
2019/11/01(金) 10:29:23.31ID:9RAuu3bH
>>755
それだけならMinorClassを前方宣言するだけでincludeいらない
2019/11/01(金) 10:32:58.37ID:XsK+HhVl
>>757
MinorClassの実体をメンバにするなら前方宣言じゃだめ
ポインタなら前方宣言にできる
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だとどうなる?よくよく考えよう
2019/11/01(金) 10:43:47.44ID:9RAuu3bH
>>758
そんなんかすまん
勘違いしてた
2019/11/01(金) 11:01:10.12ID:XsK+HhVl
privateメンバをポインタ型にする手間や不都合とpImplの手間や管理コストのどっちを取るかだろうな
基本的には継承するクラス以外のincludeは排除できる
ヘッダ内部での外部ライブラリのincludeは可能な限り避けるべき
2019/11/01(金) 11:10:39.87ID:ichmHmwx
>>760
オブジェクトを生成するには「大きさの情報」が必要だと覚えておくとわかりやすいと思う。
クラスの内容がわからないと大きさが確定しないから生成できないけど、ポインタの大きさはわかる。
2019/11/01(金) 11:11:24.16ID:ichmHmwx
>>759
そういう状況があることはわかるよ。
でもそんなことしねーよって話なんだってば。
2019/11/01(金) 13:00:57.84ID:aQLx28Zt
>>763
それお前個人がしたことないって言う経験談?
それとも他の代替手段を取るってこと?
先に言っておくと前者ならすっこんでろ
2019/11/01(金) 13:23:21.41ID:ichmHmwx
>>764
俺がしたことないという経験談だが、
ここで pimpl が割に合わないと出ている意見は
そういう状況があんまりないという内容だということの説明でもある。

そういう状況で必要だってのはわかってるし、
そういう状況にあるなら使えばいいよ。
それはわかってるんだよ。
だからしつこく説明しないいよっていう話。
2019/11/01(金) 13:29:29.85ID:ichmHmwx
要するに >>759 はまるで見当はずれのこと言ってんなぁという感想。
2019/11/01(金) 14:32:22.73ID:o99mOnqi
単機能ライブラリ作って渡す仕事してる人にとっては日常なんで、検討外れとか抜かされても勝手なこと言ってんなあとしか
まあ、OSSしかやらないとか、最終の実行バイナリしか作らないとか、そもそも個人プレーで人にプログラム成果物渡したりしないとかなら、
pimplの価値わからんという気持ちになるのはしょうがないし、それが世界の全てだと思っちゃうのかもな
2019/11/01(金) 14:59:10.92ID:ichmHmwx
>>767
それが全てといってるわけじゃなくて、
pimpl がどうしても必要! と言ってる人こそライブラリ販売の世界しか見てないという話をしてんの。
2019/11/01(金) 15:01:01.21ID:ichmHmwx
いる場所ではいるし、いらない場所ではいらないという当たり前のことしか言ってないつもりなんだけど。
2019/11/01(金) 15:04:22.58ID:E92xj2lK
全員知らないことの方が多いのに相手が自分の分野のことを知らないと無知扱いするのは草生える
2019/11/01(金) 16:16:45.44ID:luUnrp0t
>>759
そもそもVer. 1.0でコンパイルしたクラスライブラリをVer. 8.0でコンパイルしたオブジェクトとリンクできるの?
10年間互換性保ってるC++コンパイラの名前教えてくれるかなw
2019/11/01(金) 18:28:24.75ID:5daK08GN
動的リンクなら古いコンパイラでコンパイルしたライブラリが使えるかどうかはOSの互換性次第だろ
2019/11/01(金) 18:36:37.94ID:VMz8o48U
>>766
一般的な現象よ
周回遅れのやつに絡まれたらキョトンとしちゃうやろ
今の餃子ちゃんがまさにそれよ
幼稚園児に絡まれたお兄さんみたいになっとる
2019/11/01(金) 18:38:39.54ID:OIX3BcSW
あぁ、メモリーレイアウトでずっこけるやつか。
2019/11/01(金) 19:03:19.99ID:luUnrp0t
>>772
マングリングって知ってるか?
そもそもC++のクラスライブラリを簡単に動的リンクできるOSってあるのか?w
776デフォルトの名無しさん
垢版 |
2019/11/01(金) 19:25:46.93ID:4VV6x0Mu
まんぐりがえし
2019/11/01(金) 19:41:21.97ID:N2gtvXpa
comはクラスライブラリになるのかな
いろいろ面倒だけど
2019/11/01(金) 19:44:45.43ID:8Rp12Rb3
念のため確認だけど、pimplの代替手段については把握されてる前提でOK?
http://site.oukasei.com/?p=148
2019/11/01(金) 19:56:12.78ID:o5qRV/vr
リンク問題はABIの話だよな?
それはリンカのオプション次第じゃないのん?
2019/11/01(金) 20:26:50.93ID:luUnrp0t
>>779
広い意味だとABI
リンカのオプションで前のバージョンに対応してるとかの例もあるけど10年前まで対応してる例とかあるのかな?
2019/11/01(金) 20:51:10.72ID:62eq0k7o
>>778
結局、pimplのI/F用外側クラスを基底クラスに、implを派生クラスにするってだけでやってることはpimplと同じ
むしろ以下の点でより悪い
・I/F用のクラスと実装用のクラスに不必要な継承関係が導入されていらない複雑度が増える
・↑と同じことだが、実装用クラスがI/F用クラスと同じメンバ関数を実装することが強制される
・コンストラクタが使えず、独自のファクトリ関数の使い方を利用者に覚えさせる必要がある
・利用者に生ポが露出する。生ポを避けたい利用者は自分でunique_ptrなどで包まなければならない
・I/F用クラスを利用者が勝手実装して混入させることを許す

上に挙げたのはポリモさせたい場合はメリットでもあるんだが、ポリモを意図しない単独クラスに継承構造なんか入れるべきではない
2019/11/01(金) 21:03:35.70ID:gYA8Bkai
いっそのことヘッダオンリーライブラリにしようぜ
2019/11/01(金) 21:04:43.68ID:tPmTFLHa
>>766
検討はずれかどうかは意見が分かれるかもしれないけど、pimplには速度的な
オーバーヘッドが少しはあるのと、記述が分かりにくいような気がするので、
個人的にはまずは使うのを躊躇する。

ポインタのワンクッションを置いても速度的なオーバーヘッドが問題ない場合には、
単純なクラスへのポインタを使ってそのクラスの実装に依存しないようなコードを書く
ことはある。しかし、pimpleと言われているものよりずっと単純なもの。
pimplの定義もよく分からないので、それが全く同じものかどうかは分からない。
2019/11/01(金) 21:10:39.48ID:gbx33EDY
>>752
目指す理想が違いすぎるやつとは話にならん
2019/11/01(金) 21:13:24.24ID:tPmTFLHa
>>778
そういう風に、C++の抽象クラス(Javaではinterfaceと呼ばれるものと等価
だったはず)を使うと分かり易いですね。
2019/11/01(金) 21:15:27.37ID:N2gtvXpa
実装方法もいろいろでメリットデメリットもいろいろやから好きなの使えばええねん
2019/11/01(金) 21:18:26.92ID:tPmTFLHa
interface を使って、データメンバを隠したい場合は、new CXxxx にあたる部分を
どうやって実装するかの問題になるんですね。グローバル関数にしてしまう
方法もありますが、確か、デザインパターンの「Factoryパターン」というものが
それに該当したかもしれません。
2019/11/01(金) 21:34:43.52ID:aQLx28Zt
>>768
依存切りたいならpimplと言ってるところに
依存気にしてないからpimpl不要っていってるのがお前
不要ならすっこんでろって
2019/11/01(金) 22:03:59.28ID:p6e3QfJv
COM最強やな
2019/11/01(金) 22:07:08.70ID:tPmTFLHa
>>789
めちゃくちゃ使いにくい。
2019/11/01(金) 22:10:22.26ID:U/a7Wx11
>>784
目指す理想がpimpl?
確かに話にならんなw
2019/11/01(金) 22:13:09.54ID:U/a7Wx11
>>790
ただ20年間I/F変えないようにするにはあの程度の手間は必要なわけで
まあもうちょいスマートにできるんじゃないかなって思うところは多々あるけど
2019/11/01(金) 23:37:29.12ID:NpcjLENm
>>789-790

COMが使いづらいと言うか、C++とstdとSTLとWindows APIとCOMの流儀が
ごちゃまぜで、メモリの確保の仕方と文字列の扱いが混沌を極めてるw
2019/11/01(金) 23:41:19.87ID:NpcjLENm
.NETは(特に起動の)遅ささえなければ、ずっと簡単だよな。
C#でもなんでもさ

0.5〜1秒クラスの起動速度の差が気になることやってるんで、
久々にC++使ってるけど大変すぎ

でもまあ20年ぐらい前に比べれば随分と楽になってるけど
2019/11/02(土) 03:47:26.33ID:dYVngRw/
>>791
> 目指す理想がpimpl?

違うけど、おまえなんかに説明してもチンパンジーに因数分解を教えるようなものだ
2019/11/02(土) 06:10:30.99ID:QFHeQDAU
std::filesystem はいいな。やっとまともに使えるものができたって感じ
C++17からって遅すぎだと思うが
2019/11/02(土) 07:36:04.48ID:esIitHWU
>>795
単に馬鹿にされてることに気づけよw
2019/11/02(土) 08:38:38.13ID:dYVngRw/
>>797
おまえがな
799デフォルトの名無しさん
垢版 |
2019/11/02(土) 08:48:08.81ID:E6JKa4Vv
文字コード周りの混沌ぶりに比べれば、文字列クラス乱立なぞ微々たるものよ。
2019/11/02(土) 09:26:25.84ID:esIitHWU
>>798
まさかまだ気づいてないとか?w
801デフォルトの名無しさん
垢版 |
2019/11/02(土) 09:27:02.38ID:s0WXD89V
>>776
それだ!
2019/11/02(土) 09:49:41.56ID:smHgTNTv
>>759
ver1.0とver8.0がライブラリの呼び出し規約レベルで違うならpimplでも静的にはリンクできないし、
ver1.0とver8.0がCRTレベルで違うならやっぱ静的にはリンクできないし、
ver1.0とver8.0がライブラリの呼び出し規約レベルで同じかつCRTレベルでも同じならpimplでなくとも静的にリンクできるし、

pimpl関係無くね?
2019/11/02(土) 09:57:16.61ID:l25LSbph
ライブラリだとpimplというかvoid*にして、各種操作をc関数として公開
c++ではラップしたinterfaceクラスを提供って形だろ
実装側はc++の実装クラスにstatic_castして後はc++の世界で書く

pimplは中途半端だから使わない
2019/11/02(土) 10:06:07.78ID:egbBWGD9
windowsのハンドルがそんなだね
中身どんぐらい変わってるんだろうか
2019/11/02(土) 10:06:09.13ID:smHgTNTv
void*からC++クラスのポインタ型にstatic_castってできたっけ、
2019/11/02(土) 10:12:48.91ID:l25LSbph
出来るよ
多態使いたかったらbase ptrとvoid*の相互変換をする

派生ptrからvoid*に直接変換すると危険
2019/11/02(土) 10:18:39.64ID:smHgTNTv
>>806
安全性と危険性が反対くね?
void*が指すアドレスは構造体やクラスの境界に整列している保証が無いのでは…

>>804
WIN32の内部において、ハンドルが単なるindexでなくポインタとして使われているという根拠は?
確かに正体がvoid*だったりするが、ポインタだとしたらOS視点では
INVALID_HANDLE_VALUE判定が
難しくなるのであった、(一般論として
2019/11/02(土) 10:20:03.47ID:dYVngRw/
>>800
だからおまえがな
2019/11/02(土) 10:21:28.65ID:dYVngRw/
static_cast<void*>は最派生クラスにダウンキャストだね
2019/11/02(土) 10:27:48.65ID:egbBWGD9
>>807
外見維持してることが重要なんであって中身でなにをどうしてようがはどうでもいいがな
2019/11/02(土) 10:28:34.71ID:smHgTNTv
やべービルド通るわこれ
うちのコンパイラは壊れてるな…
int g_nSomeValue;
int main()
{
int* p = &g_nSomeValue;
int* q = static_cast<int*>(p);
printf("p=0x%p\n", q);

return 0;
}
2019/11/02(土) 10:30:01.86ID:smHgTNTv
貼りまつがえた、
誤: int* p = &g_nSomeValue;
正: void* p = &g_nSomeValue;
2019/11/02(土) 10:39:33.14ID:l25LSbph
void*は型情報が完全に消えるから、
型が完全に一つだとわかっているならそのままstatic_castすればいい

多態だと派生型からvoid*に直接変換してしまうと、void*から戻す場合に基底ポインタには戻せる保証がない
2019/11/02(土) 10:39:40.95ID:RcR6NuMm
>>802
依存している構造体のサイズやレイアウト変わったらアウトだろ
2019/11/02(土) 10:45:21.22ID:RcR6NuMm
>>803
C++でラップしてる時点で中途半端なのはかわらない
むしろ手間増えてる
2019/11/02(土) 10:46:18.05ID:pWYzNK5/
過去の遺産のCOMなんて使いにくいて横で話ししてるやろ
10年後の環境のことまで気にする必要ないんだよ
ばっさり捨ててその時代にあったものを作るべき
無理に資産転用とか互換性とか気にするからクソが生まれる
2019/11/02(土) 10:47:10.74ID:l25LSbph
pimplで実装隠したところで、
引数に例えばstd::string使うだけでコンパイラバージョン変えたときの保証は無くなるしなぁ
2019/11/02(土) 10:56:15.43ID:vl/bFsjF
要するに>>759は知ったかが無理矢理考えたアホストーリーと言うことでいいかな?w
2019/11/02(土) 10:57:17.10ID:vl/bFsjF
>>808
ああ、もうそういう返ししかできないのか…
高い理想とか笑えるわw
2019/11/02(土) 11:06:42.79ID:smHgTNTv
>>814
pimplだと構造体の実装はライブラリ側に完全隠蔽なのでその観点はおかしい
つかjコンパイラのバージョンも関係無い
2019/11/02(土) 11:16:21.46ID:smHgTNTv
>pimplだと構造体の実装はライブラリ側に完全隠蔽なのでその観点はおかしい
何が言いたいのかというとライブラリ使用側がライブラリが依存する構造体メンバに直アクセスする前提なら
そんなライブラリはpimplにできんだろとゆーこと
つまりpimpl対非pimplの比較の想定が変
非pimpl条件のライブラリのインターフェース仕様だけ抽象度を下げて議論しても仕方が無い
2019/11/02(土) 11:16:32.42ID:EX+sUHBj
>>816
そんなライブラリ誰が使いたがるんだよ
2019/11/02(土) 11:23:46.22ID:l25LSbph
オープンソースやクローズドでも社内での話だったらソースごと提供すれば終わる話だし
社外提供なら多言語で使えるようにcのAPIを出すのが普通じゃないのか
その上で各言語用のラッパーも提供されるってのがありがちなパターン
2019/11/02(土) 11:37:12.15ID:pWYzNK5/
>>822
現時点で有用なら使うでしょ
逆に10年前からメンテされてなくて現時点でも使われてるライブラリなんてある?
メンテされてるかよりその時代に即したものに乗り換えてくでしょ
2019/11/02(土) 11:50:05.18ID:EX+sUHBj
いやメンテなり機能追加はしろよ
仕様がらっと変わるのわかってるもんなんて使いたくないわ
作り手も使う側めんどいだろ
826デフォルトの名無しさん
垢版 |
2019/11/02(土) 12:26:20.48ID:DuRHh2CY
D なぜ流行らなかったし
Go 突き抜けてる
Rust ちょっと意識高い系
Nim 有望
JULIA 話にならない
2019/11/02(土) 12:50:14.99ID:esIitHWU
>>824
ライブラリじゃないけど例えばExcel2003とかまだCOM経由なら動かせるでしょ
COMの泥臭いインターフェースだから面倒だけどね
2019/11/02(土) 12:54:19.41ID:pWYzNK5/
>>827
動かせるけどクソだよね?
だから新しいのつかうじゃん?
つうかoffice系は延々と互換性意識してメンテされ続けてるじゃん
2019/11/02(土) 13:22:43.30ID:esIitHWU
>>828
俺が言ってるのはCOMの話な
Excelの話はケースバイケースだからなんとも言えんし俺には関係ないからどうでもいい
2019/11/02(土) 13:28:52.76ID:pWYzNK5/
>>829
COMの中身詳しくないんだけど一切メンテされてないの?
今までwinは山ほど脆弱性をupdateしてるけど、そういう中にCOM周りの修正とかなかったの?
間違いなくあったと思うんだよね。
COMに限らず現状使えるMS産のもので10年間内部が未修正のものなんて多分存在しないんじゃない?
だから10年後のことだけなんて考慮する必要なくて将来に渡り有益ならどうせメンテされるし一時的なもので将来無益になるなら消え去るんだよ
2019/11/02(土) 13:32:28.90ID:pWYzNK5/
>>829
なんか前後で俺の主張がずれてる感じで申し訳ない
2019/11/02(土) 13:52:05.38ID:esIitHWU
>>830-831
インターフェースの話とインターフェースの先にあるライブラリとかCOMサーバーの話をごっちゃにしてないか?
2019/11/02(土) 14:07:55.01ID:RcR6NuMm
>>821
勘違い甚だしい
ライブラリ使用者に無関係で見せたくないからpimplで隠すという話をしてる隠さなかったら無用にincludeが増えるし、最悪そのinclude先の仕様変更で互換がくずれる場合もあると
2019/11/02(土) 14:12:10.51ID:RcR6NuMm
>>823
そう、それが結局いまだによくも悪くもベストプラクティス
わかってないやつ多いんだよ
いきってc++で自称モダンな設計で作り上げてあとで泣きながらcのインタフェース作るはめになる
たいてい機械的なラッパーではすまないからな
2019/11/02(土) 14:34:01.62ID:SXOl8GCi
void*的な「ハンドル」を経由して操作するやーつ
C由来のインターフェースは強いな
2019/11/02(土) 14:53:41.66ID:QFHeQDAU
>>827
> ライブラリじゃないけど例えばExcel2003とかまだCOM経由なら動かせるでしょ

Excelとか以前に、DirectXやシェル(エクスプローラー)そのものがCOMだから
2019/11/02(土) 14:55:12.97ID:QFHeQDAU
>>832
そうそう。脆弱性の話はCOMじゃなくてDCOM。

もちろんCOMも脆弱性とは無関係ではないんだけど、
それはC++がバッファーオーバーフローと無関係ではないのと
同じようにCOMの設計自体の問題じゃない
2019/11/02(土) 15:00:15.19ID:4213U75y
ComPtr使ってる?
2019/11/02(土) 15:04:46.15ID:i1zx37WV
Essential COMの第1章で、C++からいかにしてCOMに至るか書いてあるけど、あの流れすごい好き
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況