Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Class Method Inheritance

I have recently transitioned from Java to C++, and I am having some difficulties working out how class inheritance works exactly. Currently, I have the class Weapon and the class Minigun. Minigun inherits the class Weapon, which means it should have the methods and variables that Weapon defines. My issue is that I have a private constant static int inside Weapon called rate, and a public method that returns an integer called getRate(). getRate() simply returns the rate variable as defined in the class. When Minigun extends Weapon, and I set the rate inside Minigun, the getRate() method still returns the constant from the Weapon class, even though it is being called on the Minigun class. I thought it would act like Java, and the intherited method would use the modified variable inside Minigun. Currently I have to do the following;

Weapon.h

#ifndef __WEAPON__
#define __WEAPON__

class Weapon
{
    public:
        virtual int getRate()
        {
            return rate;
        }
    private:
        const static int rate = 0;
};

#endif

Minigun.h

#include "Weapon.h"

#ifndef __WEAPON_MINIGUN__
#define __WEAPON_MINIGUN__

class Minigun: public Weapon
{
public:
    int getRate(); // I have to define this here, and create it inside Minigun.cpp
private:
    const static int rate = 30;
};

#endif

Minigun.cpp

#include "Minigun.h"

int Minigun::getRate() // Is there a way so I do not need to type this out for every class that extends Weapon?
{
    return rate;
}
like image 565
Jack Wilsdon Avatar asked Oct 22 '22 01:10

Jack Wilsdon


2 Answers

Weapon instances would return a rate of Weapon::rate through getRate() and Minigun instances would return a rate of Minigun::rate.

Because the method getRate() is virtual a Weapon pointer or reference to a Minigun instance would return a rate of Minigun::rate.

If only the rate variable changes in the derived classes, a template class would require less coding than the dynamic polymorphic version. The template version would look like:

    template<int Rate = 0>
    class Weapon
    {
        public:
            int getRate() // no need for virtual anymore
            {
                return rate;
            }
        private:
            const static int rate = Rate;
    };

    class Minigun: public Weapon<30> {};
like image 104
a.lasram Avatar answered Oct 24 '22 18:10

a.lasram


Don't have it be static. For example:

#include <iostream>

class Weapon {
    public:
       Weapon();
       virtual int Rate();
       virtual void Rate(int r);
    protected:
       int rate;
};

Weapon::Weapon() {
    rate = 10;
}

class Minigun : public Weapon {
    public: 
         Minigun();
};

Minigun::Minigun() {
    rate = 30;
}

int Weapon::Rate() {
    return rate;
}
void Weapon::Rate(int r) {
    rate = r;
}

int main() {
    Minigun ThisGun;
    Weapon AnyGun;
    std::cout << ThisGun.Rate() << std::endl;
    std::cout << AnyGun.Rate() << std::endl;
    AnyGun.Rate(15);
    std::cout << AnyGun.Rate() << std::endl;

    return 0;
}

We declare a protected int in the base class. This means any derived class that inherits the base class will have that variable as well. You only declare a variable static if you want only one instance of that variable shared for all instances of that object.

Base constructors will get called before the derived constructor. You can reset default values in your derived constructor for objects of that specific type. Public functions will call the most derived virtual function. In this case, we want Minigun to behave the same for our rate functions so we simple do not implement any function for Minigun so the Weapon functions are called instead. output is:

30
10
15
like image 37
Chemistpp Avatar answered Oct 24 '22 17:10

Chemistpp