アカウント名:
パスワード:
地獄継承クラスを見せられて俺のコードの方が綺麗だ、いやそれ違うだろう・・・とか理解できない?いや、これ有名なイディオムなんですよ・・・とか理解できない?デザインパターンっていうのが有りましてね・・・とか余りの無知に疲れる(半笑)
C++は罠が多すぎてちゃんと理解してるプログラマなんかこの世に存在しないだろ。例が悪すぎる。
C++のえらい人達ほど理論だけで実戦でコード書いてないからあてにならん。
C++ の標準化課程で、委員会の提案した仕様についてコンパイラ屋がダメ出ししてたのを見て、開かれているなと思うのと同時に、他の仕様もとりあえず動いてるだけなんじゃないかと疑うようになりましたよ。
> 他の仕様もとりあえず動いてるだけなんじゃないかと疑うようになりましたよ
実際、絶対やっちゃいけないけど、文法的には正しいとかいう機能が沢山ありますからねえ。(virtual なメソッドがあるクラスなのにデストラクタが virtual ではないとか、デストラクタ内でメンバを delete しているクラスなのにデフォルトのコピーコンストラクタを使ってるとか)
Cのポインタだってやっちゃいけない操作あるじゃんって話もあるけど、C++はCと比べても落とし穴の数が多すぎて、C以上に怖いような。超優秀なメンバーだけ揃ってる開発チームなら超強力な言語なんでしょうけど。
非常に危険なコードですよ、それ。
virtual 使ってるってことはすなわち、基底クラスへのポインタ経由であれこれ操作することを意味します。(基底クラス経由で操作する可能性がゼロなら、virtual にする必要がない)当然、delete することも想定すべきです。
例外的に決して delete されないこともあるだろうし、C++の設計思想として、少しでも効率を向上できる可能性がある場合には、そうできるようにしておくっていうのも知ってるけど、開発者の能力が揃ってないような現場を考えた場合、その設計思想が危険なコードを許す結果になってるってことは議論の余地がないと思います。
ほとんど使わない危険な機能はそもそも提供しない方が、一般の開発現場や、保守を長期にわたって行う状況では望ましいと思います。そして、C++の設計思想はそういう開発現場に向けたものではない。
> まず、私が出した例では、クラスAのデストラクタはprotectedですので、クラスBを外部から使用する限り、A*に対してdeleteすることは不可能です。
しかしクラスAのメンバ関数内で、delete することはできますよね。型安全性の保証としては不十分です。もちろん、熟練したC++プログラマのみで構成されるプロジェクトであれば、問題ありませんが。
> それはC++に求めるべきものではないです。
その点、すなわちC++はそういう安全性を求める言語ではないというのは、元から同意している点です。
ちなみに、他のオブジェクト指向言語を見ると、そもそも virtual などという予約語に
>> C++は、それでも実現できないような、厳しい性能要件を達成するために、熟練したプログラマーのみ>> で利用するという条件下では、非常に優れた言語です。その条件の成立しない状況では、他の言語を>> 選択したほうが幸せでしょう。
> であるならば、なおさら絶対だめというのは納得いかないですね。そういうときこそ禁止されたら困ると思うんですけど。
まあC++で開発するのが適切なプロジェクトで、性能プロファイルをとった結果、virutalをつけるかつけないかで、意味のある性能差が出るのであれば、許してもいいと思います。そういう意味では絶対だめ
> まずvirtual縛りで開発して、あとで非virtualに変えるのだとすると、> どこを非virtualにしても大丈夫か調べなければならないわけで、> 動作速度が逼迫したときその手間がかかるリスクを負うならば、> 最初から必要のないところでは非virtualにしておけという話になってしまいます。
このあたりは、プロファイラが気軽に使えるプラットフォームか否かで変わってきそうですね。
> あ、-Wallだったりは必要なのでデフォルトじゃないですね。すいません。> 以前gccで-Wno-non-virtual-dtorをつけないと警告が出たのですが、> 変わったのでしょうか。そのときのバージョン
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
犯人は巨人ファンでA型で眼鏡をかけている -- あるハッカー
C++なんかだと良くあるw (スコア:0)
地獄継承クラスを見せられて俺のコードの方が綺麗だ、いやそれ違うだろう・・・とか
理解できない?いや、これ有名なイディオムなんですよ・・・とか
理解できない?デザインパターンっていうのが有りましてね・・・とか
余りの無知に疲れる(半笑)
Re: (スコア:0)
C++は罠が多すぎてちゃんと理解してるプログラマなんかこの世に存在しないだろ。例が悪すぎる。
Re: (スコア:0)
Re: (スコア:0)
C++のえらい人達ほど理論だけで実戦でコード書いてないからあてにならん。
Re: (スコア:0)
C++ の標準化課程で、委員会の提案した仕様についてコンパイラ屋がダメ出ししてたのを見て、開かれているなと思うのと同時に、他の仕様もとりあえず動いてるだけなんじゃないかと疑うようになりましたよ。
Re: (スコア:0)
> 他の仕様もとりあえず動いてるだけなんじゃないかと疑うようになりましたよ
実際、絶対やっちゃいけないけど、文法的には正しいとかいう機能が沢山ありますからねえ。
(virtual なメソッドがあるクラスなのにデストラクタが virtual ではないとか、デストラクタ内でメンバを delete しているクラスなのにデフォルトのコピーコンストラクタを使ってるとか)
Cのポインタだってやっちゃいけない操作あるじゃんって話もあるけど、C++はCと比べても落とし穴の数が多すぎて、C以上に怖いような。
超優秀なメンバーだけ揃ってる開発チームなら超強力な言語なんでしょうけど。
絶対? (スコア:1)
class A {
protected:
~A() {}
public:
virtual void f() = 0;
};
class B : private A {
private:
virtual void f();
public:
A* a() { return this; }
};
とかやりませんか?
Re: (スコア:0)
非常に危険なコードですよ、それ。
Re: (スコア:1)
Re: (スコア:0)
virtual 使ってるってことはすなわち、基底クラスへのポインタ経由であれこれ操作することを意味します。
(基底クラス経由で操作する可能性がゼロなら、virtual にする必要がない)
当然、delete することも想定すべきです。
例外的に決して delete されないこともあるだろうし、C++の設計思想として、少しでも効率を向上できる
可能性がある場合には、そうできるようにしておくっていうのも知ってるけど、開発者の能力が揃ってない
ような現場を考えた場合、その設計思想が危険なコードを許す結果になってるってことは議論の余地がない
と思います。
ほとんど使わない危険な機能はそもそも提供しない方が、一般の開発現場や、保守を長期にわたって行う状況
では望ましいと思います。そして、C++の設計思想はそういう開発現場に向けたものではない。
Re: (スコア:1)
これは全くそう思いませんね。
まず、私が出した例では、クラスAのデストラクタはprotectedですので、クラスBを外部から使用する限り、A*に対してdeleteすることは不可能です。
そもそもdeleteは危険な操作です。対象となるポインタがdeleteできるものかどうかは常に注意を払われるべき問題です。deleteしてよいタイミングであるかどうかに加え、オブジェクトがnewで生成されたのか、スタック上に構築されたのか、placement newで構築されたのか、そのいずれのポインタであるかを言語上は区別できません。その判断をする能力が開発者に備わっていないというなら、deleteも生のポインタも禁止してスマートポインタ一本でやっていくほうがよほど安全でしょう。
設計思想が危険なコードを許す結果になっているのはその通りですが、その設計思想ゆえ、virtual関数を持つクラスのデストラクタは常にvirtualであるべきという主張には強く反対です。それはC++に求めるべきものではないです。
Re: (スコア:0)
> まず、私が出した例では、クラスAのデストラクタはprotectedですので、クラスBを外部から使用する限り、A*に対してdeleteすることは不可能です。
しかしクラスAのメンバ関数内で、delete することはできますよね。
型安全性の保証としては不十分です。
もちろん、熟練したC++プログラマのみで構成されるプロジェクトであれば、
問題ありませんが。
> それはC++に求めるべきものではないです。
その点、すなわちC++はそういう安全性を求める言語ではないというのは、元から同意している点です。
ちなみに、他のオブジェクト指向言語を見ると、そもそも virtual などという予約語に
Re: (スコア:1)
それはクラスAの用途と実態がマッチしてないだけです。クラスAのメンバ関数内でdeleteするなら当然デストラクタをvirtualで宣言するでしょうし、そうなったらnewでしかオブジェクトが作られないように、Bのコンストラクタもprotectedなりprivateなりにして、staticメンバ関数中でnewするといった対策も取られるでしょう。
が、そこまでやっても抜け道がどこかにあって安全性が100%でないのはC++である以上どうしようもないです。メンバ変数のポインタもdeleteできるから安全じゃないよね?とか
Re: (スコア:0)
>> C++は、それでも実現できないような、厳しい性能要件を達成するために、熟練したプログラマーのみ
>> で利用するという条件下では、非常に優れた言語です。その条件の成立しない状況では、他の言語を
>> 選択したほうが幸せでしょう。
> であるならば、なおさら絶対だめというのは納得いかないですね。そういうときこそ禁止されたら困ると思うんですけど。
まあC++で開発するのが適切なプロジェクトで、性能プロファイルをとった結果、virutalをつけるかつけないかで、意味のある性能差が出るのであれば、許してもいいと思います。
そういう意味では絶対だめ
Re: (スコア:1)
> 出るケースを経験されたのでしょうか?
比べたことはないです。
まず非virtualで開発して、その後virtualをつけるという手順でやるのだとすると、遅くなることはあっても速くなることがないので、わざわざ試す機会はなかなか来ない気がします。かといって、まずvirtual縛りで開発して、あとで非virtualに変えるのだとすると、どこを非virtualにしても大丈夫か調べなければならないわけで、動作速度が逼迫したときその手間がかかるリスクを負うならば、最初か
Re: (スコア:0)
> まずvirtual縛りで開発して、あとで非virtualに変えるのだとすると、
> どこを非virtualにしても大丈夫か調べなければならないわけで、
> 動作速度が逼迫したときその手間がかかるリスクを負うならば、
> 最初から必要のないところでは非virtualにしておけという話になってしまいます。
このあたりは、プロファイラが気軽に使えるプラットフォームか否かで変わってきそうですね。
> あ、-Wallだったりは必要なのでデフォルトじゃないですね。すいません。
> 以前gccで-Wno-non-virtual-dtorをつけないと警告が出たのですが、
> 変わったのでしょうか。そのときのバージョン
Re:絶対? (スコア:1)
> うちのようにスキルがデコボコしているチームだと無理ですので。^^;
件の会社でも新入社員のレベルはまちまちだったのですが、家庭用ゲーム機ですとメモリ管理が厳格なので、どうしてもヒープ周りの扱いは正しく身につけてもらわなければならないという切実な事情はありました。STLが原則使用禁止だったりして、好きなときにnew/deleteできる環境でC++を覚えた人からするとかなり異質な世界なので、もしかすると、あえて間違える余地を残すことで指摘の機会をつくるという効果もあったのかもしれないですね。