Thread: Virtual functions called by non-vitual?

  1. #1
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879

    Virtual functions called by non-vitual?

    Ok, this is my code (well, not yet but if it works then yes it is ):

    Code:
    class Upgrade
    {
    public:
        bool collide();
    protected:
        virtual void upgrade();
    };
    
    class Shields : public Upgrade
    {
    protected:
        void upgrade();
    };
    
    void Upgrade::upgrade()
    {}
    
    bool Upgrade::collide()
    {
        if(/*collision*/)
        {
            //disappear (I'll figure it out later)
    
            upgrade();   // <---
    
            return true;
        }
        return false;
    }
    
    void Shields::upgrade()
    {
        stuff();
    }
    If I then call collide(), and there is a collision, will Shields::upgrade() be called or will Upgrade::upgrade() be called?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  2. #2
    Registered User
    Join Date
    Jun 2002
    Posts
    151
    It depends. If you call it using a Shields object then the Shields version will execute, otherwise you'll get the Upgrade version.

  3. #3
    Registered User The Dog's Avatar
    Join Date
    May 2002
    Location
    Cape Town
    Posts
    788
    >> will Shields::upgrade() be called or will Upgrade::upgrade() be called?

    Shields::upgrade() would be called in that case.

    I think your declaration should've been:

    virtual void upgrade() = 0;

  4. #4
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Hmm, actually I thought that I needed a pointer to make it use the Shields version... but in Upgrade::upgrade(), it doesn't use a pointer. Does that matter?...

    And why do I need the "= 0" on the declaration?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  5. #5
    Registered User
    Join Date
    Jun 2002
    Posts
    151
    If it's being called from a Shields object then it's implicitly using a pointer; to the vtable.

    >And why do I need the "= 0" on the declaration?

    You'd include this if you wanted to prevent an Upgrade object from be created and to force all directly dervied classes to implement ::upgrade.

  6. #6
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Oh, ok... I'll just grab a dictionary

    You'd include this if you wanted to prevent an Upgrade object from be created and to force all directly dervied classes to implement ::upgrade
    That means "if you wanted to prevent an Upgrade object from being created and if you wanted to force all directly derived classes to implement ::upgrade"? Or "if you... and if you didn't want to force all (...)"?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    He is right.

    Code:
    class Upgrade
    {
    public:
        bool collide();
    protected:
        virtual void upgrade();
    };
    
    void Upgrade::upgrade(){cout << "class Upgrade calls upgrade" << endl;}
    
    bool Upgrade::collide()
    {
        if(1 == 1)
        {
            //disappear (I'll figure it out later)
    
            upgrade();   // <---
    
            return true;
        }
        return false;
    }
    
    
    
    
    class Shields : public Upgrade
    {
    protected:
        void upgrade();
    };
    
    
    
    
    void Shields::upgrade()
    {
     cout <<  "class Shields calls upgrade" << endl;
    }
    
    
    
    
    int main(int argc, char *argv[])
    {
     Shields s;
     s.upgrade();
     s.collide();
     getch();
    
     return 0;
    }

    As you can see, after running the program, both s.upgrade() and s.collide() called the Sheilds version of 'upgrade()'. Note though, you could ensure that in 'collide()' that the base version of upgrade() would be called if you defined:


    Code:
    bool Upgrade::collide()
    {
        if(1 == 1)
        {
            //disappear (I'll figure it out later)
    
            Upgrade::upgrade();   // <---like so.
    
            return true;
        }
        return false;
    }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  8. #8
    Registered User
    Join Date
    Jun 2002
    Posts
    151
    >That means "if you wanted to prevent an Upgrade object from being created and if you wanted to force all directly derived classes to implement ::upgrade"? Or "if you... and if you didn't want to force all (...)"?<

    The first one.

  9. #9
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Ok, so if i do this:
    Code:
    Shields s;
    if(s.collide())
        //(do something)
    then Upgrade::collide() will be called, and it will in turn call Shields::upgrade()? (sorry, I'm slow )
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  10. #10
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Yes.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  11. #11
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Ok, thanks guys!
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  12. #12
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Just for reference here is a little terminology. When you define a function in your base class with the " = 0" it is known as a 'pure virtual function' , and any class containing pure virtual functions are called 'abstract base classes'.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  13. #13
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Okee... and are 'abstract base classes' good?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  14. #14
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Oh n/m, i'll look it up on MSDN
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  15. #15
    Evil Member
    Join Date
    Jan 2002
    Posts
    638
    Abstract base classes are useful b/c they cannot be instantiated. So if I wanted to say, have a class called Animal that was the base class of Lion and Tiger and Bear, then I could declare Lions and Tigers and Bears, but I could also declare something as just an Animal, which might not be desireable. Using a pure virtual function to abstract the base class would prevent you from accidentally declaring objects of type Upgrade, so you could be sure you always got the overriding functions of the derived classes.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 48
    Last Post: 09-26-2008, 03:45 AM
  2. Virtual Functions
    By warfang in forum C++ Programming
    Replies: 2
    Last Post: 05-07-2007, 11:14 PM
  3. Replies: 2
    Last Post: 10-02-2005, 05:04 PM
  4. virtual functions in C
    By sangi in forum C++ Programming
    Replies: 7
    Last Post: 11-19-2004, 01:25 PM
  5. Exporting Object Hierarchies from a DLL
    By andy668 in forum C++ Programming
    Replies: 0
    Last Post: 10-20-2001, 01:26 PM