Thread: Help with inheritance and virtual functions

  1. #1
    Registered User
    Join Date
    Feb 2015
    Posts
    56

    Help with inheritance and virtual functions

    Im trying to learn how to use virtual functions and inheritance, i folloiwed an example but made my own classes and functions, when i compile the program i get no errors but when the console window starts it crashes immediatley, not sure whats wrong.


    Code:
    #include <iostream>
    using namespace std;
    
    class Actor
    {
        public:
            Actor(float actorHealth, string actorName, float actorAttackPower): actorHealth(100), actorName("Default_Actor"), actorAttackPower(0) {}
            ~Actor();
    
            virtual string GetActorName(){ return actorName; }
            virtual float GetActorHealth(){ return actorHealth; }
            virtual float GetActorAttackPower(){ return actorAttackPower; }
    
        protected:
            float actorHealth;
            string actorName;
            float actorAttackPower;
    };
    
    
    class Velociraptor : public Actor
    {
        public:
            Velociraptor(float actorHealth, string actorName, float actorAttackPower): Actor(actorHealth, actorName, actorAttackPower) {}
            string GetActorName(){ return actorName; }
            float GetActorHealth(){ return actorHealth; }
            float GetActorAttackPower(){ return actorAttackPower; }
    };
    
    class TRex : public Actor
    {
        public:
            TRex(float actorHealth, string actorName, float actorAttackPower): Actor(actorHealth, actorName, actorAttackPower){}
            string GetActorName(){ return actorName; }
            float GetActorHealth(){ return actorHealth; }
            float GetActorAttackPower(){ return actorAttackPower; }
    };
    
    class Player : public Actor
    {
        public:
            Player(float actorHealth, string actorName, float actorAttackPower): Actor(actorHealth, actorName, actorAttackPower) {}
            string GetActorName(){ return actorName; }
            float GetActorHealth(){ return actorHealth; }
            float GetActorAttackPower(){ return actorAttackPower; }
    };
    
    int main()
    {
       // Create objects of type CheckingAccount and SavingsAccount.
       Velociraptor *pVelociraptor = new Velociraptor(100, "Velociraptor", 30);
       //TRex *pTRex = new TRex(100, "T-Rex", 37);
    
       Actor *pActor = pVelociraptor;
       cout << pActor->GetActorName();
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You should declare the destructor of the base class to be virtual, and also define it, e.g.,
    Code:
    class Actor
    {
        public:
            // ...
            virtual ~Actor() {}
            // ...
    };
    Then remember to delete what you new.

    Incidentally, you are overriding the virtual functions to do the same thing as the original, so that's not very useful, but I guess you're just trying to get it to compile and run correctly for now.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Feb 2015
    Posts
    56
    Ok so i changed that and deleted my object, but when its called, it just says "Default_Actor" instead of giving the name of the dinosaur.

    "Incidentally, you are overriding the virtual functions to do the same thing as the original"

    How should i do it?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by CH1156
    Ok so i changed that and deleted my object, but when its called, it just says "Default_Actor" instead of giving the name of the dinosaur.
    That's because in the constructor for Actor, you always set the hardcoded default values instead of forwarding the values provided by the invocation of the constructor. If you want default values, one option is to use default arguments, though then you should declare the constructor to be explicit unless you want implicit conversions, e.g., if this does not make sense:
    Code:
    Actor actor = 20;
    Quote Originally Posted by CH1156
    How should i do it?
    For example, perhaps a special characteristic of the velociraptor is that when it is badly injured, its effective attack power is doubled from the base value. In that case, perhaps you might do something like this:
    Code:
    #include <iostream>
    #include <string>
    
    class Actor
    {
    public:
        explicit Actor(float actorHealth=100, std::string actorName="Default_Actor", float actorAttackPower=0):
            actorHealth(actorHealth), actorName(actorName), actorAttackPower(actorAttackPower) {}
    
        virtual ~Actor() {}
    
        virtual std::string GetName() const
        {
            return actorName;
        }
    
        virtual float GetHealth() const
        {
            return actorHealth;
        }
    
        virtual float GetAttackPower() const
        {
            return actorAttackPower;
        }
    protected:
        float actorHealth;
        std::string actorName;
        float actorAttackPower;
    };
    
    class Velociraptor : public Actor
    {
    public:
        Velociraptor(float actorHealth, float actorAttackPower):
            Actor(actorHealth, "Velociraptor", actorAttackPower) {}
    
        float GetAttackPower() const
        {
            return (actorHealth < 20) ? (actorAttackPower * 2) : actorAttackPower;
        }
    };
    
    class TRex : public Actor
    {
    public:
        TRex(float actorHealth, float actorAttackPower):
            Actor(actorHealth, "T-Rex", actorAttackPower) {}
    };
    
    void print(const Actor& actor)
    {
        std::cout << actor.GetName() << " has " << actor.GetHealth()
            << " health and will attack you for " << actor.GetAttackPower()
            << " points of damage!\n";
    }
    
    int main()
    {
        Velociraptor healthyVelociraptor(100, 40);
        print(healthyVelociraptor);
        Velociraptor injuredVelociraptor(15, 40);
        print(injuredVelociraptor);
    
        TRex injuredTrex(15, 90);
        print(injuredTrex);
    }
    Notice that I declared the getter functions to be const since they do not modify the logical/observable state of the object. I simplified by not using new or delete; polymorphism comes into play in the print function instead.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Feb 2015
    Posts
    56
    Ok thanks. So could i apply this to most of my classes that use polymorphism and inheritance? I'm still struggling with how to actually implement it. I understand what it does but when I go to use it myself I always seem to do it wrong. at least, thats what other people tell me. I just want to do it the "Right" way. I want to back up to just inheritance for a moment. I would normally do something like this:

    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    
    
    class KActor // Killable Actor, only applies to living beings.
    {
        public:
            KActor(){}
            ~KActor(){}
    
    
            Attack();
    
    
            void SetActorWeight(float KAct_wgt);
            float GetActorWeight()const {return actorWeight;}
    
    
            void SetActorName(std::string KAct_actrNme);
            std::string GetActorName()const {return actorName;}
    
    
        protected:
            float actorWeight;
            std::string actorName;
    };
    
    
    void KActor::SetActorName(std::string actrNme){
        actorName = actrNme;
    }
    
    
    void KActor::SetActorWeight(float wgt){
        actorWeight = wgt;
    }
    
    
    
    
    class Dinosaur : public KActor
    {
        public:
            Dinosaur(){}
            ~Dinosaur(){}
    };
    
    
    class TRex : public Dinosaur
    {
        public:
            TRex(){}
            ~TRex(){}
    };
    
    
    class Player : public KActor
    {
        public:
            Player(){}
            ~Player(){}
    };
    
    
    
    
    int main()
    {
        Dinosaur Velociraptor;
    
    
        Velociraptor.SetActorName("Velociraptor");
        Velociraptor.SetActorWeight(210);
    
    
        std::cout << "Dinosaur Info: \n" << std::endl;
    
    
        std::cout << "Name: " << Velociraptor.GetActorName() << std::endl;
        std::cout << "Weight: " << Velociraptor.GetActorWeight() << " LBS." << std::endl;
    
    
    
    
        Player player;
    
    
        player.SetActorName("Dino Slayer");
        player.SetActorWeight(260);
    
    
        std::cout << "Player Info: \n" << std::endl;
    
    
        std::cout << "Player Name: " << player.GetActorName() << std::endl;
        std::cout << "Player Weight: " << player.GetActorWeight() << std::endl;
    
    
    }
    Is this the correct way to do inheritance? I believe it is, however i've been told that using getters and setters is a big no no except when its necessary.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by CH1156
    I want to back up to just inheritance for a moment.
    Inheritance usually goes together with polymorphism. It doesn't have to, but then that means you're probably inheriting to inherit implementation, which can be fine, but often also can be done in other ways, e.g., perhaps composition would be better, or perhaps you should do private inheritance to inherit implementation because there isn't really an is-a relationship.

    Quote Originally Posted by CH1156
    Is this the correct way to do inheritance?
    Sure, but if you think about it, you only need the KActor class. For example:
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    
    class KActor // Killable Actor, only applies to living beings.
    {
    public:
        void SetActorWeight(float KAct_wgt);
        float GetActorWeight()const {return actorWeight;}
    
        void SetActorName(std::string KAct_actrNme);
        std::string GetActorName()const {return actorName;}
    private:
        float actorWeight;
        std::string actorName;
    };
    
    int main()
    {
        KActor Velociraptor;
    
        Velociraptor.SetActorName("Velociraptor");
        Velociraptor.SetActorWeight(210);
    
        std::cout << "Dinosaur Info: \n" << std::endl;
    
        std::cout << "Name: " << Velociraptor.GetActorName() << std::endl;
        std::cout << "Weight: " << Velociraptor.GetActorWeight() << " LBS." << std::endl;
    
        KActor player;
    
        player.SetActorName("Dino Slayer");
        player.SetActorWeight(260);
    
        std::cout << "Player Info: \n" << std::endl;
    
        std::cout << "Player Name: " << player.GetActorName() << std::endl;
        std::cout << "Player Weight: " << player.GetActorWeight() << std::endl;
    }
    That is, inheritance added no value at all to your code, and in fact worsened it by adding unnecessary code that needed to be written and read for no good reason.
    Last edited by laserlight; 10-01-2017 at 09:57 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Feb 2015
    Posts
    56
    ah, yeah thats a big oversight on my part. What would be an example of inheritance using the code i posted above? I'm unsure what would really be specific to a dinosaur that wouldnt work for all of them.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by CH1156
    I'm unsure what would really be specific to a dinosaur that wouldnt work for all of them.
    Basically, you have a solution looking for a problem :P

    I suggest that you start by reading these articles, in PDF format:
    The Open-Closed Principle
    The Liskov Substitution Principle
    The Dependency Inversion Principle
    The Interface Segregation Principle
    They should give you an idea of some ways by which inheritance and polymorphism might be used.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Feb 2015
    Posts
    56
    Thanks, I'll take a look through those when i get some time. So could you show me some code of what you think is the perfect example of polymorphism and multiple inheritance? Having some code to look at and dissect would help me understand better i think.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with virtual function and virtual inheritance
    By shaxquan in forum C++ Programming
    Replies: 2
    Last Post: 08-30-2010, 10:39 AM
  2. Inheritance and pure virtual functions
    By Swerve in forum C++ Programming
    Replies: 3
    Last Post: 03-12-2010, 01:30 PM
  3. inheritance, polymorphism, and virtual functions
    By cs_student in forum C++ Programming
    Replies: 8
    Last Post: 08-04-2008, 08:47 AM
  4. Inheritance and virtual functions
    By Cryptomega in forum C++ Programming
    Replies: 5
    Last Post: 02-28-2003, 02:59 PM
  5. inheritance & virtual functions
    By xagiber in forum C++ Programming
    Replies: 3
    Last Post: 02-11-2002, 12:10 PM

Tags for this Thread