2017-10-26 4 views
0
#include<iostream> 
using namespace std; 

int main(){ 
    class c1{ 
     public: 
     c1(){ 
      cout<<"constructing c1"; 
     } 

    }; 


    class c2:private c1{ 
     public: 
     c2(){ 
      cout<<"constructing c2"; 
     } 
    }; 
    c2 inst1; 

} 

q1。アクセスがプライベートであっても、ベースオブジェクトの派生オブジェクトが呼び出されるのはなぜですか? つまり、c1がプライベートとして継承されている場合でもc1()が呼び出されるのはなぜですか?なぜベースコンストラクタが継承されているのですか?どうすればそれを防ぐことができますか?

q2。ここではc1が継承されていますが、どうしたら起こるのを防ぐことができますか?

+0

コンストラクターが継承していません。コンストラクタと継承についてお読みください。 – aghilpro

+0

@aghilpro - C++ 11では、コンストラクタの継承のオプションが追加されました。ここで起こっていることではありませんが、これらの用語は互いに素ではありません。 – StoryTeller

+0

@StoryTeller私はそれについて読んでいます。 http://www.cplusplus.com/forum/general/17261/フィードバックに感謝します。 – aghilpro

答えて

2

これは継承されません。 c2は-c1である。 c2オブジェクトの一部であるc1サブオブジェクトがあります。

c2コンストラクタは、パラメータを持たずデフォルトの構築に使用できるため、c1を自動的に呼び出すようになっています。

あなたはこれが起こることをさらに説得力のある場合は、c1 c'torにパラメータを追加してみてください:

c1(int){ 
    cout<<"constructing c1"; 
} 

今ではc1を構築デフォルトに使用することはできません。これは、プライベートまたはパブリックの継承とは何の関係もありません

c2() : c1(0) { 
    cout<<"constructing c2"; 
} 
+0

「c2 is- a c1 " – rimiro

+0

@rimiro - [これを意味します](https://en.wikipedia.org/wiki/Is-a#C.2B.2B)。 – StoryTeller

0

:あなたは、いくつかの整数値を使用してc2で基本クラスc'torを呼び出す明示的によって解決することができる素敵なエラーが発生し、取得します。 基本クラスのコンストラクタが呼び出された後に派生クラスのコンストラクタが呼び出され、デストラクタが逆の順序で呼び出されます。

それはここで継承でC1のオブジェクト指向プログラミング

+0

最後の文で書いた内容は真実ですが、いくつかの言語(Javaなど)では動作が異なります。 – lorro

+0

私はJavaの専門家ではありません。しかし、私がコンストラクタシーケンスについて理解する限り、それは同じように動作します。ガベージコレクタによるデストラクタはありません。これはあなたが意味することですか? – sandwood

+0

私は、Javaでは、明示的な呼び出しで子クラスの親ctorを呼び出すことを意味しました。 OPは明示的なctorコールがないために混乱しているようです(ベースにはデフォルトのctorがあるので暗黙的です)。単純なc1()がうまく動作しないため、コールをどこに置くべきかを知らないことによって、私の最初のコメントは、このことについてあまりにも簡単すぎて誤解を招くかもしれない。 – lorro

0

のfondamental重要なポイントですが、どのように私は起きてからのを防ぐことができますか?

短い答え:あなたはそれを防ぐことはできません。 派生オブジェクトには、継承のためにすべての親オブジェクトがサブオブジェクトとして含まれています()。したがって、オブジェクト全体を初期化するために、コンパイラーはすべてのサブオブジェクトに対して各コンストラクターを呼び出す以外に選択肢はありません。

ただし、親のコンストラクタの動作には、特定の引数を指定して呼び出すことで影響を与えることができます。このことを考えてみましょう:

class Base { 
    Data _data; 
protected: 
    Base(bool load_from_cache) { 
     if(load_from_cache) _data = read_cache(); 
     else _data = read_database(); 
    } 
}; 

class Derived : public Base { 
public: 
    Derived() : Base{ true } { } // specify from where to read the data 
}; 

関数オブジェクトを渡すように、カスタム動作を注入するための他の多くの可能性がありますが、ラムダは、CRTPは、あなたがそれを言います。

関連する問題