CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5

Threaded View

  1. #1
    Join Date
    Apr 2005
    Location
    Quebec
    Posts
    13

    Virtual inheritance error

    Hi guys,

    I'm using virtual inheritance to solve the "diamond" problem in C++. The following code works fine when compiled with gcc, but does not under Visual C++.

    Interface A allows one to print() and clone() the object. Interface B inherits (virtually) from A, and overrides the clone() function to actually return a B*, not merely a A*. Several other classes not included here are assumed to inherit virtually from A.

    The C class implements B.

    Let c be an instance of class C. c can print and clone itself as expected.
    However when c is cast to B*, it can print itself but cloning does NOT work. The problem is when calling C::clone(), the 'this' pointer is 2 bytes away from its correct address.

    When using regular inheritance (from B to A), it works. When B does not override clone(), it works as well.

    Am I missing something...? Or is my implementation somehow illegal?

    Thanks!
    Ives

    Code:
    #include <iostream>
    using namespace std;
    
    // Base Interface A
    class InterfaceA
    {
    public:
      virtual void print() = 0;
    
      virtual InterfaceA* clone() = 0;
    };
    
    // Interface B inherits virtually from A
    class InterfaceB : public virtual InterfaceA
    {
    public:
      virtual InterfaceB* clone() = 0;
    };
    
    // C implements interface B
    class ConcreteC : public InterfaceB
    {
    public:
      ConcreteC(int _c) : c(_c) { }
    
      virtual void print()
      {
        cout << c << endl;
      }
    
      virtual ConcreteC* clone()
      {
        return new ConcreteC(c);
      }
    
    private:
      int c;
    };
    
    int main(int argc, char *argv[])
    {
      ConcreteC *c = new ConcreteC(1);
      c->print();       // prints "1"
    
      ConcreteC *c_clone = c->clone();
      c_clone->print(); // prints "1"
    
      InterfaceB *b = c;
      b->print();       // prints "1"
    
      InterfaceB *b_clone = b->clone(); // doesn't work!
      b_clone->print(); // oups! prints some random number
    }
    Last edited by IvesRogne; October 15th, 2009 at 10:27 AM. Reason: Removed unnecessary dynamic_cast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured