パスワードを忘れた? アカウント作成

こちらは、Phorkさんのユーザページですよ。 スラドのTwitterでストーリをフォローしよう。

7088708 comment

Phorkのコメント: Re:絶対? (スコア 1) 143

> 複数人開発でその方針が適用できるというのは、正直羨ましい開発環境です。
> うちのようにスキルがデコボコしているチームだと無理ですので。^^;

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

Phorkのコメント: Re:絶対? (スコア 1) 143

> 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で警告が出ます。

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

今は一人ですが、以前勤めていたゲームメーカーでこのようにしていたので、引き続き同じ方針でやっています。
7088195 comment

Phorkのコメント: Re:絶対? (スコア 1) 143

仮想関数呼び出しのオーバーヘッドを気にすることがあります。実際デストラクタでそれが問題になるのは極めてレアケースだとは思いますが、私としては不正なdeleteの使用法に対する予防よりは、性能に対する予防を優先したいです。
7087961 comment

Phorkのコメント: Re:絶対? (スコア 1) 143

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

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

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

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

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

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

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

繰り返しますが、ローカルルールで禁止するのはいいですよ。でも、絶対じゃない。
7085145 comment

Phorkのコメント: Re:絶対? (スコア 1) 143

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

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

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

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

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

Phorkのコメント: 絶対? (スコア 1) 143

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

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

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

とかやりませんか?
typodupeerror

長期的な見通しやビジョンはあえて持たないようにしてる -- Linus Torvalds

読み込み中...