CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Mar 2009
    Posts
    82

    virtual base conceptual questions

    Hello!

    I got few things that I do not understand about virtual bases.

    I got this code:

    Code:
    class PoweredDevice
    {
    public:
        PoweredDevice(int nPower)
        {
    		cout << "PoweredDevice: " << nPower << endl;
        }
    };
    
    class Scanner: virtual public PoweredDevice
    {
    public:
        Scanner(int nScanner, int nPower)
            : PoweredDevice(nPower)
        {
    		cout << "Scanner: " << nScanner << endl;
        }
    };
    
    class Printer: virtual public PoweredDevice
    {
    public:
        Printer(int nPrinter, int nPower)
            : PoweredDevice(nPower)
        {
    		cout << "Printer: " << nPrinter << endl;
        }
    };
    
    class Copier: public Scanner, public Printer
    {
    public:
        Copier(int nScanner, int nPrinter, int nPower)
            : Scanner(nScanner, nPower), Printer(nPrinter, nPower), PoweredDevice(nPower)
        {
        }
    };
    Now, when you create a Copier class, you will get only one copy of PoweredDevice that will be shared by both Scanner and Printer.

    However, this leads to one more problem: if Scanner and Printer share a PoweredDevice base class, who is responsible for creating it? The answer, as it turns out, is Copier. The Copier constructor is responsible for creating PoweredDevice. Consequently, this is one time when Copier is allowed to call a non-immediate-parent constructor directly
    Since when the constructor creates objects?

    Does the Copier creates the PoweredDevice and how the sharing is done? I do not understand.

    Also why virtual bases are created before non-virtual bases?

    Why virtual classes are said to run on run-time and not compiling time?

    Thanks in advance.

    Regards.

    P.S Here is link that I read from.

  2. #2
    Join Date
    Oct 2008
    Location
    Singapore
    Posts
    195

    Re: virtual base conceptual questions

    Quote Originally Posted by StGuru View Post
    Since when the constructor creates objects?
    Yes, constructor creates objects but does not allocates memory which you are alluding to.

    Quote Originally Posted by StGuru View Post
    Does the Copier creates the PoweredDevice and how the sharing is done? I do not understand.
    Yes, it does and the same PoweredDevice is then shared by all 3 - Scanner, Printer and Copier

    Quote Originally Posted by StGuru View Post
    Also why virtual bases are created before non-virtual bases?
    Because Printer and Scanner rely on PoweredDevice and it is necessary to create it before either of these 2.

    Quote Originally Posted by StGuru View Post
    Why virtual classes are said to run on run-time and not compiling time?
    I do not understand this question.

  3. #3
    Join Date
    Feb 2009
    Posts
    326

    Re: virtual base conceptual questions

    I have expressed my views, correct me if I am wrong:

    rohshall
    ----------
    My understanding of the purpose constructor is mainly used to initialize members of the class.

    So I suppose it would have to allocate memory so that it can initialize the member variables.

    In this case, when an object of the class Copier is created, that object would contain the members of Scanner and Printer. (PoweredDevice is indirectly inherited).

    StGuru
    ---------
    Why virtual classes are said to run on run-time and not compiling time?

    Are you referring to the binding being done at runtime for virtual functions instead of compile time ?

    If that is question, then mentioned below is the reason:

    Binding is a process by which, which function (whether base class or derived class's function) to be invoked is determined.

    For normal functions, this is determined at compile time based on the object type calling it

    For virtual functions, this is determined at runtime based on the object pointed (or referenced) by the base pointer (or reference).

    The late binding allows the program to execute to different functions based on the what the pointer (or reference) points to.

  4. #4
    Join Date
    Mar 2009
    Posts
    82

    Re: virtual base conceptual questions

    Thanks for the replies.


    So constructor do allocate memory for objects right?

    In this case the PoweredDevice is created by Copier directly, and then Scanner and Printer inherit the members from PoweredDevice, but how does Copier inherits the members from Scanner and Printer?

    Because Printer and Scanner rely on PoweredDevice and it is necessary to create it before either of these 2.
    But in this case PoweredDevice is created first which is non-virtual base.

    Binding is a process by which, which function (whether base class or derived class's function) to be invoked is determined.

    For normal functions, this is determined at compile time based on the object type calling it

    For virtual functions, this is determined at runtime based on the object pointed (or referenced) by the base pointer (or reference).

    The late binding allows the program to execute to different functions based on the what the pointer (or reference) points to.
    Reply With Quote
    Yes, I have heard about binding proccess, but I do not make difference (or I can understand) why (is there any reason) that it should be run-time and not compile time.

  5. #5
    Join Date
    Oct 2006
    Posts
    616

    Re: virtual base conceptual questions

    Quote Originally Posted by StGuru View Post
    Yes, I have heard about binding proccess, but I do not make difference (or I can understand) why (is there any reason) that it should be run-time and not compile time.
    Consider this example:
    Code:
    class Animal
    {
    public:
       virtual void Speak() = 0;
    };
    
    class Dog : public Animal
    {
    public:
       virtual void Speak() 
       {
          std::cout << "Whoof";
       }
    };
    
    class Cat : public Animal
    {
    public:
       virtual void Speak() 
       {
          std::cout << "Meow";
       }
    };
    
    int main()
    {
       Animal* a = NULL;
       
       std::cout << "Enter 1 for dog or 2 for cat: ";
       int sel = -1;
       std::cin >> sel;
       if (sel == 1)
       {
          a = new Dog();
       }
       else if (sel == 2)
       {
          a = new Cat();
       }
       
       if (a)
       {
    	  a->Speak();
       }
    }
    Lets say you were to bind virtual functions at compile time. When the line marked in red is compiled, what would it bind it to ? the Dog ? the Cat ? both ? none ?

    You can easily see that the decision must be done during runtime - it's the users choice that determines which instance you would have. Any run-time variable may affect the binding (not just the user).

    Regards,
    Zachm
    Last edited by Zachm; July 4th, 2009 at 06:36 AM.

  6. #6
    Join Date
    Feb 2009
    Posts
    326

    Re: virtual base conceptual questions

    As Zachm has stated, it is something determined at runtime.

    The advantage of this, is you can make your program work differently by just altering the value of the pointer or reference, because it would be invoking different functions. It gives the programmer more flexibility.

    The reason why the binding would have to be done at run time is because, only at runtime would you know what the pointer points to.

    I suppose, it would help if you can look at simpler example of virtual function, then come back to this.

    ===================================================
    I have just pasted below the basics of virtual functions (hope it helps) - Excuse me if this is redundant information

    Virtual Function Fundamentals
    --------------------------------------
    Case 1 (trivial) - Always an object of a class has ONLY access to the members of the class it belongs and the class it inherits.

    Case 2 - Only when the calling object is a reference or a pointer and it refers / points to an object that belongs to a different class type will a virtual function make a difference


    Points to Note -
    -------------------
    A virtual function will make a difference ONLY when the calling object is a reference / pointer

    An object of the derived class is also an object of the base class. (a concept of inheritance)

    "this" pointer is a pointer to the calling object and class type of the this pointer is the same as that of the class to which it belongs.

    Virtual property is inherited, though not explicitly mentioned in the derived classes, the virtual property is still inherited.

    For a normal function binding is done at compile time. Depending on the class type of the calling object, the corresponding implementation of the function is invoked. (applicable whether the calling object is a pointer / reference or an object of the class)

    For virtual function binding is done at run time (late binding). Depending on the class type of the object to which the calling object (reference / pointer) refers / points to, the corresponding implementation of the function is invoked.
    Last edited by Muthuveerappan; July 4th, 2009 at 07:11 AM.

  7. #7
    Join Date
    Mar 2009
    Posts
    82

    Re: virtual base conceptual questions

    Thanks for the replies. It really helped me.

    I got few questions more:

    Does the constructor allocates memory for the object of the class?

    For example. (if normal inheritance rules apply) :

    Lets imagine that the class Scanner doesn't exist in the code above:

    Code:
    class PoweredDevice
    {
    public:
        PoweredDevice(int nPower)
        {
    		cout << "PoweredDevice: " << nPower << endl;
        }
    };
    
    class Printer: public PoweredDevice
    {
    public:
        Printer(int nPrinter, int nPower)
            : PoweredDevice(nPower)
        {
    		cout << "Printer: " << nPrinter << endl;
        }
    };
    
    class Copier: public Printer
    {
    public:
        Copier(int nPrinter, int nPower)
            : Printer(nPrinter, nPower)
        {
        }
    };
    
    int main()
    {
        Copier cCopier(1, 2, 3);
    }
    Now with the line Copier cCopier(1, 2, 3); the default constructor of cCopier will allocate memory for it, and then the Printer constructor will be called (which also would create memory for Printer), and finally with calling the constructor of PowerDevice, the PowerDevice would be created. Is this the way it works?

    Thank you.

  8. #8
    Join Date
    Feb 2009
    Posts
    326

    Re: virtual base conceptual questions

    Before answering your question, just have mentioned some basic stuff, after which I have answered your question:

    Without Inheritance
    -------------------------
    When an object of a class is created, its constructor of that class is invoked.

    The constructor allocates memory for the members of the class.

    With Inheritance
    ---------------------
    Like in your example the class Printer inherits PoweredDevice.

    So when you create an object of Printer, the following happens:
    1) Constructor of the class Printer invoked - allocates memory for members of the class Printer
    2) Constructor of the class Printer in turn invokes the constructor of the class PoweredDevice - allocates memory for members of the class PoweredDevice

    The above is true whether it is a virtual base or not.

    Note - Order of execution is such that the constructor of base object is executed, then the constructor of derived object is executed and so on.

    Similarly when an object of the class Copier is created, the constructor of Copier would be invoked, which would invoke the constructor of Printer, which in turn would invoke the constructor of PoweredDevice

    Default constructor is one without arguments, and the default constructor would be invoked if there is no explicit mention of any specific constructor (I mean constructor with arguments).

    Your Question
    ------------------
    The last program would throw an error because you are trying to invoke a constructor of the class Copier that you have not defined.

    line 34: error: no matching function for call to 'Copier::Copier(int, int, int)'

    Assuming in the main function you declared the following object:
    Copier cCopier(1, 2);

    In that case the the following constructors would be called:
    1) Copier(int nPrinter, int nPower)
    2) Printer(int nPrinter, int nPower)
    3) PoweredDevice(int nPower)

    In fact in your example there was no default constructor defined and it wouldn't be called because you are explicitly calling constructors with parameters.

  9. #9
    Join Date
    Mar 2009
    Posts
    82

    Re: virtual base conceptual questions

    Thank you very much for the help.
    Yes I missed Copier (1,2,3) while copying the whole code.

    But in the first post with the keyword "virtual" there is not normal inheritance since the first object which is created is PoweredDevice. Then the constructors of Printer and Scanner are ignored, and there is not duplicate creation of PoweredDevice.

Tags for this Thread

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