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

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

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

    • by Anonymous Coward

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

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

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

          • by Anonymous Coward on 2013年01月13日 0時26分 (#2304961)

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

            親コメント
            • by Anonymous Coward

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

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

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

              • by Phork (15003) on 2013年01月13日 10時59分 (#2305046)
                > 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

                超性能ソフトウェアを組むのでなければ超優秀でなくてもいいけど、メンバーのレベルの統一は強く求められる言語だよね。
                道を外れるコーダーがいても、他メンバーの指摘で補正できるレベルならいい。

                MPLでも、90年代のオブジェクト指向でも、例外禁止、使い終わったメモリは手動で解放なんてルールでも、
                正しく書けばそれなりのパフォーマンスは出る、そういう言語。
                でも言語のサポートするパラダイムが広すぎるから、文化の違う開発者同士では
                綺麗汚いを超えたレベルで相互理解不能なコードになったりする。

              • by Anonymous Coward

                横レスですが
                C++の問題はメンバーのレベルよりも、長い間勉強していなかったベテランのロートル化がやばいと思っています。
                歴史の長い言語ゆえに酷い有様のベテランが上層部にいてどうにもならない事が多々あり。

              • by Anonymous Coward

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

              • by Phork (15003) on 2013年01月13日 11時31分 (#2305057)
                本当ですか?危険なのって基底クラス(この場合A)のポインタに対してdeleteする場合だけじゃないんですか?
                親コメント
              • by Anonymous Coward

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

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

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

              • by Phork (15003) on 2013年01月15日 10時54分 (#2305991)
                > 当然、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 などという予約語に

              • by Phork (15003) on 2013年01月15日 18時57分 (#2306317)
                > しかしクラスAのメンバ関数内で、delete することはできますよね。

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

                が、そこまでやっても抜け道がどこかにあって安全性が100%でないのはC++である以上どうしようもないです。メンバ変数のポインタもdeleteできるから安全じゃないよね?とか明らかに普通じゃない書き方を引き合いに出されたらキリがない。性能と安全性を天秤にかけて、安全性のほうが重要だとなればローカルルールで禁止するのは結構ですが、ちょっとでも誰かが危険なコードを書く余地があるから何人たりとも絶対だめだというのはおかしいでしょう。

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

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

                > あるいは、 #2304967 で挙げているようなコーディングを、規約やコンパイラオプションで禁止するか
                > ですね。C++の有名な解説書(Effective C++)でも、禁止を勧めていたはずです。

                デフォルトでwarningを出すコンパイラがほとんどなんじゃないでしょうか。もちろん私はoffにしますが。

                繰り返しますが、ローカルルールで禁止するのはいいですよ。でも、絶対じゃない。
                親コメント
              • by Egtra (38265) on 2013年01月15日 19時02分 (#2306318)

                protectedな非virtualデストラクタの主な適用対象は、基底クラスにvirtual関数が全くない場合だと思います。基底クラスの分のvtableを完全に省略できることがその理由です。

                この例だと基底クラスAはほかにvirtual関数を持っており(どのみちAのvtableが必要)、デストラクタを非virtualにする有難みがあまりないので、そこまでしなくてもいいのではかな(素直にAのデストラクタをvirtualにする)と私なら思います。

                なお、protectedな非virtualデストラクタ自体は熟練というほどでもないテクニックだと思います。More Exceptional C++やModern C++ Designに取り上げられているようです(私は残念ながらどっちも読んだことがない)。最も単純な例がnoncopyable(More C++ Idioms/コピー禁止ミックスイン(Non-copyable Mixin) [wikibooks.org])でしょう。

                親コメント
              • by Anonymous Coward

                #2306317 のACです。

                > この例だと基底クラスAはほかにvirtual関数を持っており、デストラクタを非virtualにする
                > 有難みがあまりないので、そこまでしなくてもいいのではかなと私なら思います。と私なら思います。

                ですよね。
                私もそう思いますし、Effective C++ もそういう感じの趣旨だったかと思います。
                にも関わらず、言語仕様的には非 virtual を許してますし、Phorkさんのように、virtualメンバ関数のある
                基底クラスのデストラクタを非virtualにすることも実際に行っていると主張する方がいるわけです。
                こういう状況で、プログラマの質や意見の揃わない、ある程度大

              • by Anonymous Coward

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

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

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

              • by Phork (15003) on 2013年01月15日 19時47分 (#2306346)
                仮想関数呼び出しのオーバーヘッドを気にすることがあります。実際デストラクタでそれが問題になるのは極めてレアケースだとは思いますが、私としては不正なdeleteの使用法に対する予防よりは、性能に対する予防を優先したいです。
                親コメント
              • by Anonymous Coward

                #2306317 のACです。

                私もどちらかというと性能は気にするほうですが、virutalのあるなしで変わるような
                定数倍のコストは、設計・コーディング時は気にしません。
                その段階で気にするのは、計算量的なコストだけです。

                実際に動かしてみて性能が足りない場合には、プロファイルをとって、ボトル
                ネックとなる部分だけを局所的にチューニングします。
                最適化を最後にやるのは、Knuthの勧め

              • by Phork (15003) on 2013年01月15日 20時44分 (#2306379)
                > Phorkさんは、virtualメンバ関数のあるクラスのデストラクタを非virtualにすることで、有意な性能差が
                > 出るケースを経験されたのでしょうか?

                比べたことはないです。

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

                デストラクタではないのですが、あるプラットフォームのあるC++コンパイラ(代替はない)で、最初は仮想関数を使用していたが、オーバーヘッドが大きすぎてswitchに書き換えるハメになった、という話なら聞いたことがあります。(以後そのプラットフォームではC++を使用せずCで開発することになった・・・)

                > Linuxを含むUNIX系OSではメジャーだと思われる gcc 4.6.3 の場合、デフォルト、あるいは
                > -Wall オプションつきだけでは警告が出ません。

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

                手元のMSVC2010Expressだと/Wallで警告が出ます。

                > お一人で開発されているのでしょうか?
                > それとも複数人で開発されてますか?

                今は一人ですが、以前勤めていたゲームメーカーでこのようにしていたので、引き続き同じ方針でやっています。
                親コメント
              • 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++を覚えた人からするとかなり異質な世界なので、もしかすると、あえて間違える余地を残すことで指摘の機会をつくるという効果もあったのかもしれないですね。
                親コメント

アレゲは一日にしてならず -- アレゲ研究家

処理中...