C++类方法继承

5
我最近从Java转到C++,在理解类继承方面遇到了一些困难。目前,我有一个叫做Weapon的类和一个叫做Minigun的类。 Minigun继承了Weapon类,这意味着它应该具有Weapon定义的方法和变量。我的问题是,在Weapon类中有一个叫做rate的私有常量静态整数,并且有一个返回整数的公共方法叫做getRate()getRate()只是简单地返回类中定义的速率变量。当Minigun扩展Weapon时,我设置Minigun内部的速率,但是getRate()方法仍然返回Weapon类中的常量,即使它被调用在Minigun类上。我以为它会像Java一样,继承的方法将使用Minigun中修改的变量。目前,我必须执行以下操作;

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

尝试在minigun.cpp中使用return Minigun::rate;。无法保证结果。 - Chemistpp
@Chemistpp 我的Minigun.cpp运行良好,我想完全从Minigun.cpp中删除getRate()函数,并使用已在Weapon中定义的函数。 - Jack Wilsdon
从minigun类中删除rate属性和getrate函数。当您在minigun上调用这些函数时,它们将只调用继承的函数。 - Chemistpp
当我移除它时,Weapon内的getRate()被调用(这正是我想要的),但它返回的是基础Weapon类内的“rate”常量,而不是Minigun内的常量。 - Jack Wilsdon
1
我不确定重载是否适用于静态类成员变量,但如果它是const的话,为什么不直接使用返回值的函数(例如return 30;)呢? - Jonathan Potter
2个回答

2
Weapon实例通过getRate()返回Weapon::rate,而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> {};

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

我们在基类中声明了一个受保护的整数。这意味着继承基类的任何派生类都将拥有该变量。只有当您希望该变量的所有实例共享一个实例时,才会声明变量为static
派生构造函数之前将调用基本构造函数。您可以在特定类型的对象的派生构造函数中重置默认值。公共函数将调用最具体的虚函数。在这种情况下,我们希望Minigun的速率函数表现相同,因此我们简单地不实现任何Minigun函数,以便调用Weapon函数。输出如下:
30
10
15

我曾试图避免在构造函数中设置变量(我不记得为什么,大概是为了保持变量分离)。然而,这似乎是实现我想要的功能的最佳方法。谢谢 :) - Jack Wilsdon
我的版本似乎仍然存在问题。当我在Minigun.cpp中使用构造函数Minigun::Minigun() { rate = 30 }时,会出现一个错误,指出Weapon::rate是私有的。除了使用setter/getter组合之外,我还能做些什么? - Jack Wilsdon
protected: 确保它被声明为保护类型 - Chemistpp
1
如果您真的需要设置私有变量,请创建一个受保护的(或公共的)setter。 - Patricio Rossi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接