抽象基本クラスのコンストラクターを保護する必要があることをどこかで読みましたか? これが推奨される理由と、保護されていない場合に悪用される可能性があるのはなぜですか?
2 に答える
これが推奨される方法だと思う場合は、実際にこれを推奨している人に尋ねてください。C++ の抽象クラスは、少なくとも 1 つの純粋仮想関数を持つクラスです。とにかく、コンパイラはそのようなクラスのインスタンスを作成することを許可しません。保護されたコンストラクターでそれを支援することはあまり意味がありません。これはあなたが提供した情報に基づいています。著者には理由があるかもしれませんが、概念を誤解している可能性があります。
その提案の要点は、what-if、コアの可読性、およびメンテナンスにあると思います。
C++ では、クラスに純粋仮想メソッドがある場合、それは抽象的であると見なされ、自動的にインスタンス化できなくなります。そのために保護された ctors/dtors は必要ありません。抽象クラスのオブジェクトのようなものを作成するカンフーな方法がいくつかありますが、それを行う方法を知っている場合、それはあなたのパラダイムの問題です:)
ただし、「抽象」という用語は、クラスの目的の単なる一般的な説明と見なすこともできます。そのようなすべての「抽象」クラスが単に純粋な仮想メソッドを必要とするだけであると要求するのは非常に奇妙です。そのクラスにとって意味がない場合はどうなりますか? クラスを「抽象」としてマークするためだけに、まったく無関係な pv-method を導入する必要があります.. ctors を保護されているものとしてマークすることにより、your-class-without-pure-virtuals も自由に作成できないようにします。
メンテナンスへの影響もわずかです。いくつかの仮想メソッドと 1 つの純粋な仮想メソッドを持つ完全に抽象化されたクラスがあるとします。ctors/dtors を public のままにします。次に、半年後、クラスにパッチを適用/アップグレード/変更し、純粋仮想を「純粋」ではなく、デフォルトの実装を持つように変更します。おっと。これで、クラスが作成可能になりました。[不自然な例のために、純粋な仮想が実装できるという事実を意図的に無視します]。
もちろん、まったく別の問題は、そのような仮想メソッドのない抽象ベースは何の役に立つのでしょうか? フラグベースのセミポリモーフィズムを構築する以外に使用例が見つかりません:
struct Base { protected: base(){} public: int type; }
struct Derived1:Base { derived1(){type=1;} int shoesize; string codename; }
struct Derived2:Base { derived2(){type=2;} string name, family; }
派生1/2をベースポインターで渡し、「type」フラグでそれらのタイプを検出し、後で手動でキャストできます.RTTIなし、vtableなし、非常に軽いオブジェクト。時々あなたはそれを必要とします。
したがって、それらを保護することにはいくらかの利益がありますが、その利益は..まあ、小さいです。