C++相談室 part153
レス数が1000を超えています。これ以上書き込みはできません。
stlコンテナを継承するのはアウトだろ。
うまくやらないとデストラクタが呼ばれなくなっちゃうぞ そもそもC++ではデストラクタを仮想にしてないってことは「継承すんなよ」って宣言だからなぁ なんで継承しないようにしたか意見表明文みたいなモンはどっかにあるのか? 仮想関数化するとしない場合に比べて余分なコストがかかるから、必要な理由がない限り基本的にそれは避けるということじゃないかな C++は1クロックでも速く動作させるために非仮想関数をデフォルトにしたのは理解できる
Javaは動作速度よりもオブジェクト指向の継承動作の一貫性を重視してすべて仮想関数にした、これも時代を考えれば理解できる
C#もJavaと同じくデフォルトを仮想関数にしておいて欲しかったのだが、C#はC++を尊重してデフォルト非仮想関数なんだよね
これはちょっと残念 継承して機能追加っていうのがオブジェクト指向的にもどうかと思うね finalキーワードがこの時代にあれば間違いなく付けただろうな
文句言ってる奴はガイジ >>903
継承すんな、は言いすぎ。
private継承なら問題ないと思うけど。実際たまに使われているし。 デストラクタが仮想ではないものを継承したときの具体的な問題は
スライシングが起こりうるということと、
起こってもコンパイラが (少なくともコンパイル時には) 捕捉できないことが多いということにあって、
スライシングが起こらないように使う分には問題はない。
設計的に綺麗かどうかはまた別の話だけど。
shared_ptr が (デストラクタが仮想でなくても) 元の型のデストラクタを呼んでくれたりするんで、
場合によってはそういう設計もアリということなんだと思う。 >>910
デストラクタが仮想なものを継承してもスライシングは起こりうるよね?そこは関係なくね?
https://en.wikipedia.org/wiki/Object_slicing
> In C++ programming, object slicing occurs when an object of a subclass type
> is copied to an object of superclass type: the superclass copy will not have
> any of the member variables defined in the subclass. ... C++自由すぎてしんどいな
後方互換性と引き換えに払った代償か >>911
スライシング自体は起こるけど、それで予想外のことやメモリ管理の矛盾は起こり難い。 自由すぎて困る部分はLinterを併用することで勝手に回避しろってことかな だってCの設計思想が「人間を信用する」だもん
セキュリティが重視される現代的な言語のベースとしては致命的に合ってないんだよね >>913
やっぱり関係がわからない。
デストラクタが仮想ではないものを継承したときに限ってスライシングが予想外のことや
メモリ管理の矛盾につがなる例をひとつでいいから見えてもらえない? A <|- B, C みたいなときにB, CをnewしてA*として管理しようとすると破棄の時にAのデストラクタしか呼ばれない >>911
仮想でないデストラクタが話題のスコープなのに、スライシングにスコープを移したら議論にならないでしょ。
911) デストラクタが仮想なものを継承する→スライシングになるものが存在する
という命題は
910) デストラクタが仮想ではないものを継承する→スライシングになるものが存在する
という命題と矛盾するわけではない(両立する)ので、その議論はあんまり意味がない。 >>910
> スライシングが起こらないように使う分には問題はない。
ここもおかしいんだよね。
デストラクタが仮想ではないものを継承して派生クラスのオブジェクトを new で作って
基底クラスのポインタを通して delete したら未定義動作になるわけだけど、
これはスライシングを起こしていなくても問題になる。
「派生クラスのオブジェクトを new で作って基底クラスのポインタを通して delete」のことを
「スライシング」と呼んでる気配もあるんだけど、それは明らかに誤りだろうし。 >>900
変更ってどうやるの?
毎回好きな引数を与えよってこと?
面倒なので、自分の好きな引数を自分のコードの中ではデフォルトにできれば良いのにと思ったのだが、こういう考えは間違っていますか デストラクタはpublic仮想かprotected非仮想かpublic非仮想finalのどれかにしろ
っていう一般的結論でよくね >>925
自分で書くときはそう
標準のコンテナのように既存のクラスがそうでなかったら?が発端だからなぁ
個人的には仮想デストラクタがなければ継承はしない
(一部のイディオムを除けば)private継承にするくらいなら委譲する。 デストラクタがprotected:であっても非仮想なら継承したらアウトなんじゃ…
派生クラスの破棄時に基底クラスのデストラクタが呼ばれない
的な意味で >>924
オブジェクトを作るための関数を作ってはどうかという意味ですか?
確かにそれで良いのでそうします 【CSS規格、読書感想文】
CSSがアイデアであった段階からスクリプト言語で実装され、初の大規模採用であったネットスケープにおいてもJavascriptによって実装されていたため、規格そのものがC/C++で効率的になるよう設計されていない。※
現行の規格に対して効率的な実装を施したとしても、将来の規格バージョンで維持できると限らないため、結局、スクリプト言語と同様の非効率を許容することになる。
これはつまり、ほとんどのシンボルを動的に確保することを意味する。
※HTML5規格は、C/C++で効率的に実装できるように仕組まれている。 なるほどねー
そもそもCSSのCって要る?
もはやスタイルシートってサイト作成者が決めるものになっているよね
ユーザースタイルシートをカスケード適用できる機能もなくせばさらに効率よくできそう >>927
なんで?~Derived()が~Base()を呼ばない場合なんて存在しないぞvirtualの有無関係なく >>927
型消去とsmart ptr実装で調べるよろし。 定期的に話題になるけど、基底のデストラクタにvirtualが必要なのは
基底型のポインタでdeleteするときだけな
末端のデストラクタさえ呼べれば、次に呼ぶ基底の型は分かりきってるからね
別の言い方をすれば、常に末端の型のポインタをdeleteする分には、virtualなデストラクタなんか要らんということ ポリリズムから出汁をとったみたいないい方しますね。 まあ普通は末端の型を意識しなくて済むからこそ派生の旨味がある訳で >>936
その点については誰もが一度は通る勘違いだよなw
最初はわけも分からず機械的にvirtualつけて回ってたわ うっせえ知っとったわ素でまちがえただけじゃわ!ヽ(`Д´)ノウワーン struct A { virtual void Delete() { delete this; } };
struct B : A { void Delete() { delete this; } };
こうなってりゃ別にいらんな >>795 の同期とか奇妙な質問に思うけど、Javaからくるとそうなるんだな。 javaにだって非同期でメモリ確保するコンテナなんてないでしょ >>942
おとなしく virtual ~A() とするのにくらべて何のメリットも無いな。 「a=1 かつ b=1 以外なら実行」って条件式はどう書くの? >>950
> 「a=1 かつ b=1 以外なら実行」って条件式はどう書くの?
「「a=1 かつ b=1」以外なら実行」なら、
if (!(a == 1 && b == 1)) { 実行(); }
「a=1 かつ「b=1以外」なら実行」なら、
if (a == 1 && b != 1) { 実行(); } >>949
THX
「a=1 かつ b=1」以外なら実行、でした。
私が950でレスするのもお見通しですか?w CSSは規格の著者がサンプル実装してるというので見に行ったら、Javascriptだった。
あからさまに動的言語向けに規格が書かれているのは、そういうことでしたか。
これは辛い。 >>792
それはちょっと古臭いお馬鹿な手法でしょう
正しいやりかたは、
・呼び出し側が呼び出され側に格納エリアを提供する‥‥@
・呼び出し側が確保するべきサイズは@の前に別途問い合わせする CにはCで
#define APPBUFSZ (十分でかい整数値)
void foo() {
char buf[APPBUFSZ]; // buf[]はスタック上にとられる配列(重要
if (!func(buf, sizeof(buf))) { // 第2引数は要素数の意味とするならsizeof(buf) / sizeof([0])
バッファサイズ不足等のエラー
}
}
という黄金パターンあるんじゃー
これは原始的な見かけほど不合理というわけではない CSSはDOMの一部でありかつ意味と表記の分離の必要からCSSになった
DOMはWebページのあらゆる要素へのコントロールの実現を目的としている
という印象 >>955
Cってこのパターンでクソほど無駄なバッファ取るから全然効率的じゃないよな >>955
何が黄金なのかさっぱりわからんが…
どこでそれが黄金パターンとされているかの出典だけでも頼む 定番は>>953だろう。
事前にサイズを求めるコストがバカにならないという場合だけ別案を検討するくらいで。 大抵の場合は「事前にサイズを求める」=やり直しになりそうなんだけど >>958
左様よほど意図しない事象でも起きない限りエラー処理に行かないぐらい大き目にとる
スタック上に領域をとる場合、時間コストも空間コストもゼロとみなせるからそれで構わない
再帰呼び出しのようなきわめて深い関数呼び出し階層になるときぐらいしか問題は生じない
というわけで、プログラミングしたいこと/すべきことに対するちょっとした洞察と
アーキテクチャーに関する理解さえあれば、言うほど非効率でも不合理でもないことがわかるはず… >953
確保すべきサイズを問い合わせたときと確保して呼び出した時に必要サイズが変わっていないか気になって夜しか眠れない
(リトライしてもリトライ回数が適切かどうか気になって布団以外で眠れない) std::make_sharedにインターフェースクラスを継承したクラスを渡したいんですがエラーになりました
これは生ポインタ使えと言うことでしょうか?
https://ideone.com/QUYTgX >>965
デストラクタとコンストラクタの定義書いたらコンパイルできました
どうもありがとう chromiumのソースみると全面的にstd::unique_ptrを使ってるので、少なくともC++11 以降。 newしたクラスをdeleteすればクラス内で保持した変数のメモリも自動的に解放されるのでしょうか? >>969
「クラス内で保持」の仕方による。
deleteに伴って各メンバ変数のデストラクタが呼び出されるので、自動的に解放されるようにすることはできる。 所有してるメモリなら解放されて欲しいけど借用してるメモリは解放されちゃ困るででょ めちゃくちゃ初歩的な質問で申し訳ないのですが文字で「"」を出力したい場合はどうするのですか?
cout<<"これ→"←"<<endl;
とすると出力したい文字が「これ→」までだと認識されエラーが発生しますよね… https://ideone.com/37sNvH
バックスラッシュではうまくいったのに半角の円記号ではうまくいきません! >>975
cout << R"(cout<<"これ→"←"<<endl;)"; cout << R"fuckU(cout<<"これ→"←"<<endl;)fuckU";
ただしC++11以降な HTML5は規格通りに実装できるけど、CSSは規格通りに実装できないな。
Chromiumは、Blink以前はBison使ってたけど、Blink以降は手書きパーサになってる。
もはや、クラス名や属性名を見て処理をわけないと衝突を解決できない。 c++で出力出来ない文字とかあるんですか?
>>981
この書き方ならなんでも出力出来るんですかね?
cout<<"これ→"←"endl;)と出力したい時
cout << R"(cout<<"これ→"←"<<endl;))";
でもいけるんですか?
)が気になりますが… >>987
すいません出来ました
fuckという単語なので嘘かと思ってスルーしていました
>>982
ありがとうございます >>947
cppは論理演算子が少ないからに優しくないから先のレスのようにチマチマ等価な冗長な論理を書くしかないのが面倒だよね…
not-andなんだからnand演算子(=joint denial(↑)、論理用語)で書けりゃいいのに(もちろん裸cppで C++界隈のオッサンは普通に4文字とか猥語とかバンバン使ってちゃんとした説明するから気をつけろ template <typename A, typename B>
inline constexpr
bool nand(A&& a, B&& b)
{
return !(A == 1 && B == 1);
} プリプロセッサで演算子増やせないかな?
無理かな? マクロの識別子は英数字下線だけだかんな
あ、でも英数字下線の演算子もどきならできるね
template <typename R, typename A>
R Static_cast(A&& a) { return a; } そんなに演算子を増やしたいか?
関数でそんなに不都合には感じないが。 NANDが演算子で書けたからって別に理解しやすくもないので、いらない レス数が1000を超えています。これ以上書き込みはできません。