【问题标题】:C++ Class Method InheritanceC++ 类方法继承
【发布时间】:2013-09-06 02:04:12
【问题描述】:

我最近从 Java 过渡到 C++,但在弄清楚类继承如何准确工作时遇到了一些困难。目前,我有课程Weapon 和课程MinigunMinigun 继承了Weapon 类,这意味着它应该具有Weapon 定义的方法和变量。我的问题是我在Weapon 中有一个名为rate 的私有常量static int,还有一个返回一个名为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 我的 Minigun.cpp 工作正常,我希望从 Minigun.cpp 中完全删除 getRate() 函数,并使用已在 Weapon 中定义的函数
  • 从类 minigun 和 getrate 函数中移除速率。当你在 minigun 上调用这些函数时,它们只会调用继承的函数。
  • 当我删除它时,Weapon 内部的 getRate() 被调用(这是我想要的),但它从基础 Weapon 类内部返回“rate”常量,而不是 Minigun 内部的常量.
  • 我不确定重载是否适用于静态类成员变量,但如果它是 const 的话,为什么不直接使用直接返回值的函数(例如return 30;)。

标签: c++ inheritance methods constants static-variables


【解决方案1】:

Weapon 实例将返回Weapon::rategetRate() 的速率,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> {};

【讨论】:

    【解决方案2】:

    不要让它是静态的。例如:

    #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
    

    【讨论】:

    • 我试图避免在构造函数中设置变量(我不记得为什么,关于保持变量分开的一些事情)。但是,这似乎是实现我想要的最佳方式。谢谢:)
    • 我的版本似乎仍然存在问题。在 Minigun.cpp 中使用构造函数 Minigun::Minigun() { rate = 30 } 时,我收到一条错误消息,指出 Weapon::rate 是私有的。除了使用 setter/getter 组合之外,我还能做些什么?
    • protected: 确保它被声明为
    • 如果你真的需要私有化率,创建一个受保护的(或公共的)setter。
    猜你喜欢
    • 2011-03-03
    • 2015-01-20
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 2015-03-20
    • 2023-03-28
    • 2018-02-04
    • 2012-11-20
    相关资源
    最近更新 更多