2017-08-09 10 views
1

finalと仮想継承メソッドがこれを達成しているとは思いますが、デフォルトのプライベートクラスを除いてコンストラクタを定義しないとクラスが継承されないのはなぜですか? (基本クラスのコピーコンストラクタとコピー代入メソッドは予防策としてプライベート宣言する必要があります)デフォルトプライベートコンストラクタを定義してクラスを継承できないようにする

基本的には、基本クラスのコンストラクタがプライベートで他のコンストラクタがない場合、派生クラスが必要な場合この基底クラス拡張するために:派生クラスがあるため、基本クラスのデフォルト以外のコンストラクタを呼び出すことはできません

  • プライベートに定義されているため

    1. を派生クラスは、基本クラスのデフォルトコンストラクタを呼び出すことはできませんそのようなコンストラクタはありません

    コンパイル時にエラーが発生するため、これを乗り越える別の方法はありません。

    私はどこか間違っていると確信しています。そうでなければ、インターネット上で、これをクラスを継承不可能にする方法として、私が間違っている理由を説明してください。

  • +0

    あなたのアプローチも使用できます。もっと深く掘り下げれば、2つのアプローチがどのように異なっているのか、そしてどちらを使うべきか、もう一方を使うべきかを見つけることができます。 –

    +0

    あなたがここで何を求めているのか分かりません。あなたは*これが動作するか、*なぜ*動作するのか、それを回避する方法について疑問に思っていますか? – meagar

    +0

    @R Sahu違いを説明したり、私が読むことができるリンク関連のキーワードを教えてください。 – mualloc

    答えて

    2

    finalとプライベートコンストラクタは同じものではありません...私は、任意の実用的なケースを考えることができないと私はそれが悪いことだと思うが、そのような恐怖を行うことが可能です。

    はこのことを考えてみましょう:

    struct A final {}; 
    struct B: A {}; 
    
    int main() {} 
    

    それはコンパイルされません、それは事実です。
    は今、このことを考慮してください。

    class A { A() {} }; 
    struct B: A {}; 
    
    int main() {} 
    

    それがコンパイルされます。それで、B()コンストラクタは削除されていますが、あなたはそれを使用していません。あなたはわずかに定義変更した場合、それはコンパイルされません:(のいくつかの平均がを働くために)とにかく

    struct B: A { B(): A() {} }; 
    

    を、前の例では、ちょうど作品、その違いは何ですか?
    finalは継承を禁止します。プライベートコンストラクタではのオブジェクトを構築することはできませんが、タイプの場合でも、タイプを定義できます。

    #include<type_traits> 
    
    class A { A() {}}; 
    struct B: A {}; 
    
    template<typename T> 
    void f() { 
        static_assert(std::is_base_of<A, B>::value, "!"); 
        // ... 
    } 
    
    int main() { 
        f<B>(); 
    } 
    

    どのようにそれはあなたがAから継承することができない場合は、それがコンパイルされることである。そのため、あなたは(あまり意味がなく、あなたのアイデアを与えていない)、このような何かを行うことができますか?あなたの前提が間違っていたので、Aから継承することができます。タイプBのオブジェクトを構築することはできませんが、インスタンスの作成を試みない限り、タイプとしてBを引き続き使用できます。一方で、finalをコンパイル時にエラーが発生した場合、それはすべてです。何らかの形でタイプBを使用することはできません。

    +1

    クラスAのコンストラクタは公開されているので、私が言っていることではありません。 – mualloc

    +1

    @muallocクラスのデフォルトの可視性は 'private'なので、' class C {} {}};は 'class C {private:C {}};'と同等です。コンストラクタは実際にはpublicではありません。 2番目の例で 'B'を構築しようとすると、コンパイルされません。 – skypjack

    +1

    OK、デフォルトの表示に関する問題は正しいですし、ご説明いただきありがとうございます。それが私が探していたものです。 – mualloc

    0

    なぜ標準では禁止されていますか?理論的には、DerivedクラスをBaseクラスの友人に宣言することを妨げるものは何もありません。それは、あなたの基本クラスを拡張する唯一の可能な方法が、非常によく知られたクラスを介していることを保証するでしょう。

    struct BaseClass 
    { 
    friend struct DerivedClass; 
    
    private: 
        BaseClass() {} 
    }; 
    
    struct DerivedClass : BaseClass 
    { 
    public: 
        DerivedClass() {} 
    }; 
    
    関連する問題