Thread: Help with "virtual"

  1. #1
    Registered User
    Join Date
    Dec 2006
    Posts
    6

    Unhappy Help with "virtual"

    hi all.im new to this forum.
    ive got a problem with this program:
    Code:
    class X {
          public:
                 X() { }
                 X( int xx ) : x( xx ) { }
                 
                 int getx() const { return x; }
          private:
                 int x;
    };
    
    class Y : virtual public X {
          public:
                 Y( int xx ) : X( xx ) { }
    };
    
    class Z : public Y {
          public:
                 Z( int xx ) : Y( xx ) { }
    };
    
    int main()
    {
    Z zobj( 100 );
    cout << zobj.getx() << endl;
    it seems the "virtual" word changes something in my program and instead of getting 100 from print function i get 43-million-something.
    i have been trying to find some reference of virtual and what it does but i seem to be unlucky up till now.
    any help would be much appreciated,thank you.

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It's always the most derived class that is responsible for initializing all direct and indirect virtual bases. In other words, you have to do this:
    Code:
    class X {
          public:
                 X() { }
                 X( int xx ) : x( xx ) { }
                 
                 int getx() const { return x; }
          private:
                 int x;
    };
    
    class Y : virtual public X {
          public:
                 Y( int xx ) : X( xx ) { }
    };
    
    class Z : public Y {
          public:
                 Z( int xx ) : X(xx), Y( xx ) { }
    };
    
    int main()
    {
    Z zobj( 100 );
    cout << zobj.getx() << endl;
    Note that both Z and Y have the call to the X constructor in their initializer list. This is because if a Z object is created, the Z version is used, whereas when an Y object is created, the Y version is used.

    Are you sure virtual inheritance is what you want? You don't need it just for virtual functions. Virtual inheritance is something for multiple inheritance with common bases, and IMO the most confusing part of C++, more confusing even than template metaprogramming.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User
    Join Date
    Dec 2006
    Posts
    6
    well thanks for taking the time to answer but it really doesnt make much sense to me.
    this is a given example and im trying to understand why virtual makes 100 go to whatever-millions when i print it.

    i mean can you tell me what exactly happens if i put "virtual" in front of my class inheritance reference?

  4. #4
    Registered User
    Join Date
    Dec 2006
    Posts
    6
    noone out there knows what virtual does?
    im new to c++ and im trying to understand some basic things...

  5. #5
    MFC killed my cat! manutd's Avatar
    Join Date
    Sep 2006
    Location
    Boston, Massachusetts
    Posts
    870
    Silence is better than unmeaning words.
    - Pythagoras
    My blog

  6. #6
    Registered User
    Join Date
    Dec 2006
    Posts
    6
    thanks a lot for this link...
    the actual page doesnt give me any clues as it doesnt refer to this example of virtual but to virtual functions, but there was a link inside to what i wanted.

    Code:
    // Two classes virtually inheriting Animal:
    class Mammal : public virtual Animal {
     public:
      virtual Color GetHairColor();
    };
    class WingedAnimal : public virtual Animal {
     public:
      virtual void Flap();
    };
    i know im probably sounding very stupid saying this but i still cannot understand what the use of virtual in front of inheritance class does.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    That link (http://en.wikipedia.org/wiki/Virtual_inheritance) gives good information. You're using multiple inheritance, and you want to derive a class from two different base classes, but those base classes are each derived from another base class, which is the same for both. Or in the example, you are creating a Bat class, and a Bat is a Mammal and a Bat is a WingedAnimal. The problem is that the Bat is still only a single Animal, so you only want one version of the Animal traits in the Bat object. Having the Mammal and WingedAnimal classes use virtual inheritance solves this issue.

    As CornedBee alluded to, virtual inheritance is not a common C++ technique, why do you think you need to use it in your program?

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    If you want to understand the uses of virtual inheritance, and also the peculiar rules associated with it, study the diamond inheritance problem.
    http://en.wikipedia.org/wiki/Diamond_problem
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User
    Join Date
    Dec 2006
    Posts
    6
    thank you all for the info.
    here's the deal:
    we are given this example as stated above and i need to understand and write down why it gives millions as answer instead of 100.
    i understand the diamond problem very well the thing is he doesnt give us a diamond but actually a straight line!so why the heck would he use virtual?and past that, why does this 100-to-millions thing happen?
    thats what im actually asking.
    my deepest apologies for any misunderstanding and/or frustration i have caused.

    thanks again to all.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Madarb
    so why the heck would he use virtual?
    So he can ask questions about it, obviously.

    and past that, why does this 100-to-millions thing happen?
    I told you that. The most derived class is always responsible for initializing all direct and indirect virtual bases, so the XX(xx) in YY's initializer list is ignored when creating a ZZ object. XX's default constructor is called, so x is not initialized and has an undefined value.

    Remove XX's default constructor or make it private, and you'll see that the code won't compile.

    Edit: for further reference, read item 43 of Effective C++, 2nd edition or item 40 of the 3rd edition, or gotcha 53 in C++ Gotchas. They all deal with this stuff.
    Last edited by CornedBee; 12-14-2006 at 08:50 AM.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Registered User
    Join Date
    Dec 2006
    Posts
    6
    thanks for the info cornedBee really helpful...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A simple question about "virtual" keyword
    By meili100 in forum C++ Programming
    Replies: 2
    Last Post: 03-07-2008, 01:05 PM