Virtual Class Inheritance

Categories: Technology
Comments: 3 Comments
Published on: February 2, 2006

I am going to post some evil now, I will cover more on it later.

But a program I am working on has gotten to a point to where I ended up needing to do something like
[code]
class Base
{
public:
int value
};
class child1 : public Base { };
class child2 : public Base { };
class grandchild : public child1, public child2
{
public:
grandchild() { /* I want to access value here */ };
};
[/code]
Now with the above I can not access value directly I have to say which value I want since it comes down twice I have it as both child1::value and child2::value. Well I looked around to see what I can do with this problem, I found out about Virtual Base Classes so to deal with it check out the code below
[code]
class Base
{
public:
int value
};
class child1 : public Base { };
class child2 : public Base { };
class grandchild : virtual public child1, virtual public child2
{
public:
grandchild() { value };
};
[/code]
Now the above does work, the virtual keyword in the inheritance causes the grandchild object to get only one copy of the Base class so I can get to value just like if there was only one path to the Base class.
The problem I am dealing with is assume I now have a virtual function call getWhatAmI() that returns info that I can use to know what type of object I am working on, so I end up in a portion of the code where I have a grandchild object being pointed to by a Base pointer. I have an if statement that only happens if I am working with a grandchild object, now I have to cast back to a grandchild so I have access to the grandchild objects. But I can not just cast it any more I get the error of [code]
“error C2635: cannot convert a ‘Base*’ to a ‘grandchild*’; conversion from a virtual base class is implied”
[/code]
So now I have to find out how to cast with this virtual base class stuff.
I will post the solution when I find a good one.

3 Comments
  1. Sean says:

    /******
    Based on what you have, here’s what
    I’d do. Note that I had to make Base a
    virtual base class of child1 and child2.
    Otherwise your final example would
    not compile for me.

    After that, doing a dynamic_cast would
    give you what you want.

    But be wary of this whole thing.
    Whenever you end up with the
    infamous diamond shape in your
    inheritance model you should closely
    inspect it to see if you can remodel
    things to break that shape. Its nasty.

    ******/

    #include

    class Base
    {
    public:
    int value;

    virtual char* GetWhatAmI() {
    return “Base”;
    }
    };

    class child1 : virtual public Base {
    public:

    virtual char* GetWhatAmI() {
    return “child1”;
    }
    };

    class child2 : virtual public Base {
    public:

    virtual char* GetWhatAmI() {
    return “child1”;
    }
    };

    class grandchild : virtual public child1, virtual public child2
    {
    public:
    grandchild() { value = 5; };

    virtual char* GetWhatAmI() {
    return “grandchild”;
    }
    };

    int main()
    {
    grandchild gc;
    Base* p = &gc;
    grandchild* gcp = dynamic_cast(p);
    printf( “%s\n”, gcp->GetWhatAmI() );
    return 0;
    }

  2. Sean says:

    Oops. You beat me to it. I didn’t see the later post.

  3. You are right I do need a vertual fuction in the Base class, but I was trying to just get a quick example to get the point accross, I should have made a better point of that.

Welcome , today is Sunday, December 22, 2024