2013-09-02 4 views
1

Я недавно перешел с Java на C++, и у меня возникают некоторые трудности с разработкой того, как работает наследование классов. В настоящее время у меня есть класс Weapon и класс Minigun. Minigun наследует класс Weapon, что означает, что он должен иметь методы и переменные, которые определяет Weapon. Моя проблема заключается в том, что у меня есть закрытый константный статический int внутри Weapon, называемый rate, и открытый метод, который возвращает целое число getRate(). getRate() просто возвращает переменную скорости, определенную в классе. Когда Minigun расширяет Weapon, и я установил скорость внутри Minigun, метод getRate() по-прежнему возвращает константу из класса Weapon, хотя он вызывается в классе Minigun. Я думал, что он будет действовать как Java, а в неработающем методе будет использоваться модифицированная переменная внутри Minigun. В настоящее время я должен сделать следующее:Наследование метода класса C++

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; 
} 
+0

try 'return Minigun :: rate;' in minigun .cpp. Нет gaurentee – Chemistpp

+0

@Chemistpp My Minigun.cpp отлично работает, я хочу полностью удалить функцию getRate() из Minigun.cpp и использовать тот, который уже определен в Weapon –

+0

, чтобы удалить скорость из класса minigun и функцию getrate.Когда вы вызываете эти функции на minigun, они просто назовут унаследованные функции. – Chemistpp

ответ

1

Не иметь статического электричества. Например:

#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; 
} 

Мы объявляем защищенный int в базовом классе. Это означает, что любой производный класс, наследующий базовый класс, также будет иметь эту переменную. Вы объявляете только переменную static, если вы хотите, чтобы только один экземпляр этой переменной был общим для всех экземпляров этого объекта.

Базовые конструкторы будут вызваны до производного конструктора. Вы можете сбросить значения по умолчанию в своем производном конструкторе для объектов этого конкретного типа. Публичные функции вызовут самую производную виртуальную функцию. В этом случае мы хотим, чтобы Minigun вел себя одинаково для наших функций скорости, поэтому мы просто не реализуем никакой функции для Minigun, поэтому вместо этого вызываются функции Weapon. :

30 
10 
15 
+0

Я пытался избежать установки переменной в конструкторе (я не помню, почему, что-то о сохранении переменных отдельно). Однако это, по-видимому, лучший способ добиться именно того, что я хочу. Спасибо :) –

+0

По-прежнему, похоже, проблема с моей версией. Когда у меня есть Minigun :: Minigun() {rate = 30} 'внутри Minigun.cpp, я получаю сообщение о том, что' Weapon :: rate' является закрытым. Что я могу сделать, кроме использования компилятора setter/getter? –

+0

'protected:' убедитесь, что он объявлен как – Chemistpp

1

Weapon экземпляров вернут курс Weapon::rate через getRate() и Minigun экземпляры возвратят курс Minigun::rate.

Поскольку метод getRate() является виртуальным Weapon указатель или ссылка на Minigun экземпляра будет возвращать скорость Minigun::rate.

Если только переменная скорости изменяется в производных классах, класс шаблона требует меньше кодирования, чем динамическая полиморфная версия. Версия шаблона будет выглядеть так:

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> {};