2

consider the following :

#include <iostream>
#include <string>
using namespace std;


class A {
public:
   A(const char* sName) //conversion constructor
           : _sName(sName) {cout<<"(1)"<<endl;} ;
   A(const A& s) {cout<<"(2)"<<endl;} //copy constructor
   virtual ~A() {cout<<"(3)"<<endl;} //destructor
    void f1() {cout<<"(4)"<<endl; f2();} //Notice two commands!
    virtual void f2() =0;
  private:
    string _sName;
  };



  class B1: virtual public A {
  public:
     B1(const char* sAName, const char* sSName)
             : _sName1(sAName), A(sSName) {cout<<"(5)"<<endl;}
     B1(const B1& b1) : A(b1) {cout<<"(6)"<<endl;}
     ~B1() {cout<<"(7)"<<endl;}
     virtual void f1() {cout<<"(8)"<<endl;}
     virtual void f2() {cout<<"(9)"<<endl; f3();}
     virtual void f3() {cout<<"(10)"<<endl;}
  private:
     string _sName1;
  };



  class B2: virtual public A {
  public:
     B2(const char* sAName, const char* sSName)
             : _sName2(sAName), A(sSName) {cout<<"(11)"<<endl;}
     B2(const B2& b2) : A(b2) {cout<<"(12)"<<endl;}
     ~B2() {cout<<"(13)"<<endl;}
     virtual void f3() {f1(); cout<<"(14)"<<endl;}
  private:
      string _sName2;
  };

  class C: public B1, public B2 {
  public:
         C () : A(" this is A ") , B1(" this is " , " B1 ") , B2 (" this is " , " B2 ") {}
         C (const C& c) :  A(c) , B1(c) , B2(c) {}
         ~C() {cout<<"(15)"<<endl;}
         virtual void f1() {A::f1(); cout<<"(16)"<<endl;}
         void f3 () {cout<<"(17)"<<endl;}
  };


  int main() {
      /* some code */
      return 0;
  }

As you can see , I added in class C the implementation of C's Ctor (constructor) . What is not clear to me is why do I need also the upcast from C to A , if B1 does that job for me in its Ctor ? Meaning , if I wrote C's Ctor as :

C () : A(" this is A ") , B1(" this is " , " B1 ") , B2 (" this is " , " B2 ") {}

why can't I write :

C () : B1(" this is " , " B1 ") , B2 (" this is " , " B2 ") {}

thanks , Ronen

4

5 に答える 5

2

つまり、標準で要求されているのは、最も派生したクラスのctorで仮想ベースを初期化する必要があるためです。

より複雑な答えは、仮想ベースのベースサブオブジェクトが1つしかないためです。このサブオブジェクトは、ベースクラスごとに異なる方法で初期化される可能性があります。たとえば、あなたの例では


C () : B1(" this is " , " B1 ") , B2 (" this is " , " B2 ") {}

コンストラクター「B1」または「B2」に渡されると予想される値は何ですか。

于 2011-09-01T08:23:22.170 に答える
2

Constructor of virtual base is called before nonvirtual ansestors ctor's. In your example B1 ctor can not invoke the virtual base constructor for C as B1 ctor itself will be called later.

于 2011-09-01T08:27:44.753 に答える
1

「B1」と「B2」はどちらも「C」と同じメモリを「A」に使用するためです。「C」で「A」の構成を指定しなかった場合、「B1」または「B2」のどちらが「A」を構成する必要がありますか?

あなたの用語はここでは少し間違っています-これは「A」へのアップキャストではありません。

于 2011-09-01T08:22:29.440 に答える
1

Because your class A does not have default constructor.

Compiler generates an default constructor for every class but once you explicitly overload the constructor it assumes you want to do something special and it does not generate the default constructor and when your code tries to invoke the default constructor it leads to an error.

The following code statement:

C () : B1(" this is " , " B1 ") , B2 (" this is " , " B2 ") {}

leads to calling of the class A default constructor, which is not there at all, and hence results in an error. If you provide an default constructor for your class A that should compile fine without any errors too.

于 2011-09-01T08:23:37.127 に答える
1

Here is a quick try:

#include <iostream>

class A { public: A(int v) : m_v(v) { std::cout << "Initializing A with " << v << std::endl; } int m_v; };
class B1 : public virtual A { public: B1(int v) : A(v) {} };
class B2 : public virtual A { public: B2(int v) : A(v) {} };
class C : public B1, public B2 { public: C(int v1, int v2, int v3) : A(v1), B1(v2), B2(v3) {} };

int main()
{
    C c(1, 2, 3);

    std::cout << "c.m_v: " << c.m_v << std::endl;

    return EXIT_SUCCESS;
}

This example outputs:

Initializing A with 1
c.m_v: 1

That is, it seems that the call to A::A() is required in the most derived class because since the inheritance is virtual, it won't get called by the constructors of B1 or B2 when instantiating C.

于 2011-09-01T08:28:44.523 に答える