パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

同僚にコードがひどいと言われたら、どう反応すればいい? 」記事へのコメント

  • 地獄継承クラスを見せられて俺のコードの方が綺麗だ、いやそれ違うだろう・・・とか
    理解できない?いや、これ有名なイディオムなんですよ・・・とか
    理解できない?デザインパターンっていうのが有りましてね・・・とか
    余りの無知に疲れる(半笑)

    • by Anonymous Coward

      C++は罠が多すぎてちゃんと理解してるプログラマなんかこの世に存在しないだろ。例が悪すぎる。

      • by Anonymous Coward
        希望的観測によるとストラウストラップさんはちゃんと理解してるそうな。
        • by Anonymous Coward

          C++のえらい人達ほど理論だけで実戦でコード書いてないからあてにならん。

          • by Anonymous Coward

            C++ の標準化課程で、委員会の提案した仕様についてコンパイラ屋がダメ出ししてたのを見て、開かれているなと思うのと同時に、他の仕様もとりあえず動いてるだけなんじゃないかと疑うようになりましたよ。

            • by Anonymous Coward

              > 他の仕様もとりあえず動いてるだけなんじゃないかと疑うようになりましたよ

              実際、絶対やっちゃいけないけど、文法的には正しいとかいう機能が沢山ありますからねえ。
              (virtual なメソッドがあるクラスなのにデストラクタが virtual ではないとか、デストラクタ内でメンバを delete しているクラスなのにデフォルトのコピーコンストラクタを使ってるとか)

              Cのポインタだってやっちゃいけない操作あるじゃんって話もあるけど、C++はCと比べても落とし穴の数が多すぎて、C以上に怖いような。
              超優秀なメンバーだけ揃ってる開発チームなら超強力な言語なんでしょうけど。

              • > virtual なメソッドがあるクラスなのにデストラクタが virtual ではない

                class A {
                protected:
                    ~A() {}
                public:
                    virtual void f() = 0;
                };

                class B : private A {
                private:
                    virtual void f();
                public:
                    A* a() { return this; }
                };

                とかやりませんか?
              • by Anonymous Coward

                非常に危険なコードですよ、それ。

              • 本当ですか?危険なのって基底クラス(この場合A)のポインタに対してdeleteする場合だけじゃないんですか?
              • by Anonymous Coward

                virtual 使ってるってことはすなわち、基底クラスへのポインタ経由であれこれ操作することを意味します。
                (基底クラス経由で操作する可能性がゼロなら、virtual にする必要がない)
                当然、delete することも想定すべきです。

                例外的に決して delete されないこともあるだろうし、C++の設計思想として、少しでも効率を向上できる
                可能性がある場合には、そうできるようにしておくっていうのも知ってるけど、開発者の能力が揃ってない
                ような現場を考えた場合、その設計思想が危険なコードを許す結果になってるってことは議論の余地がない
                と思います。

                ほとんど使わない危険な機能はそもそも提供しない方が、一般の開発現場や、保守を長期にわたって行う状況
                では望ましいと思います。そして、C++の設計思想はそういう開発現場に向けたものではない。

              • > 当然、delete することも想定すべきです。

                これは全くそう思いませんね。

                まず、私が出した例では、クラスAのデストラクタはprotectedですので、クラスBを外部から使用する限り、A*に対してdeleteすることは不可能です。

                そもそもdeleteは危険な操作です。対象となるポインタがdeleteできるものかどうかは常に注意を払われるべき問題です。deleteしてよいタイミングであるかどうかに加え、オブジェクトがnewで生成されたのか、スタック上に構築されたのか、placement newで構築されたのか、そのいずれのポインタであるかを言語上は区別できません。その判断をする能力が開発者に備わっていないというなら、deleteも生のポインタも禁止してスマートポインタ一本でやっていくほうがよほど安全でしょう。

                設計思想が危険なコードを許す結果になっているのはその通りですが、その設計思想ゆえ、virtual関数を持つクラスのデストラクタは常にvirtualであるべきという主張には強く反対です。それはC++に求めるべきものではないです。
              • by Anonymous Coward

                > まず、私が出した例では、クラスAのデストラクタはprotectedですので、クラスBを外部から使用する限り、A*に対してdeleteすることは不可能です。

                しかしクラスAのメンバ関数内で、delete することはできますよね。
                型安全性の保証としては不十分です。
                もちろん、熟練したC++プログラマのみで構成されるプロジェクトであれば、
                問題ありませんが。

                > それはC++に求めるべきものではないです。

                その点、すなわちC++はそういう安全性を求める言語ではないというのは、元から同意している点です。

                ちなみに、他のオブジェクト指向言語を見ると、そもそも virtual などという予約語に

              • > しかしクラスAのメンバ関数内で、delete することはできますよね。

                それはクラスAの用途と実態がマッチしてないだけです。クラスAのメンバ関数内でdeleteするなら当然デストラクタをvirtualで宣言するでしょうし、そうなったらnewでしかオブジェクトが作られないように、Bのコンストラクタもprotectedなりprivateなりにして、staticメンバ関数中でnewするといった対策も取られるでしょう。

                が、そこまでやっても抜け道がどこかにあって安全性が100%でないのはC++である以上どうしようもないです。メンバ変数のポインタもdeleteできるから安全じゃないよね?とか
              • by Anonymous Coward

                >> C++は、それでも実現できないような、厳しい性能要件を達成するために、熟練したプログラマーのみ
                >> で利用するという条件下では、非常に優れた言語です。その条件の成立しない状況では、他の言語を
                >> 選択したほうが幸せでしょう。

                > であるならば、なおさら絶対だめというのは納得いかないですね。そういうときこそ禁止されたら困ると思うんですけど。

                まあC++で開発するのが適切なプロジェクトで、性能プロファイルをとった結果、virutalをつけるかつけないかで、意味のある性能差が出るのであれば、許してもいいと思います。
                そういう意味では絶対だめ

              • > Phorkさんは、virtualメンバ関数のあるクラスのデストラクタを非virtualにすることで、有意な性能差が
                > 出るケースを経験されたのでしょうか?

                比べたことはないです。

                まず非virtualで開発して、その後virtualをつけるという手順でやるのだとすると、遅くなることはあっても速くなることがないので、わざわざ試す機会はなかなか来ない気がします。かといって、まずvirtual縛りで開発して、あとで非virtualに変えるのだとすると、どこを非virtualにしても大丈夫か調べなければならないわけで、動作速度が逼迫したときその手間がかかるリスクを負うならば、最初か
              • by Anonymous Coward

                > まずvirtual縛りで開発して、あとで非virtualに変えるのだとすると、
                > どこを非virtualにしても大丈夫か調べなければならないわけで、
                > 動作速度が逼迫したときその手間がかかるリスクを負うならば、
                > 最初から必要のないところでは非virtualにしておけという話になってしまいます。

                このあたりは、プロファイラが気軽に使えるプラットフォームか否かで変わってきそうですね。

                > あ、-Wallだったりは必要なのでデフォルトじゃないですね。すいません。
                > 以前gccで-Wno-non-virtual-dtorをつけないと警告が出たのですが、
                > 変わったのでしょうか。そのときのバージョン

              • by Phork (15003) on 2013年01月15日 22時04分 (#2306421)
                > 複数人開発でその方針が適用できるというのは、正直羨ましい開発環境です。
                > うちのようにスキルがデコボコしているチームだと無理ですので。^^;

                件の会社でも新入社員のレベルはまちまちだったのですが、家庭用ゲーム機ですとメモリ管理が厳格なので、どうしてもヒープ周りの扱いは正しく身につけてもらわなければならないという切実な事情はありました。STLが原則使用禁止だったりして、好きなときにnew/deleteできる環境でC++を覚えた人からするとかなり異質な世界なので、もしかすると、あえて間違える余地を残すことで指摘の機会をつくるという効果もあったのかもしれないですね。
                親コメント

開いた括弧は必ず閉じる -- あるプログラマー

処理中...