派生类 C++

Posted

技术标签:

【中文标题】派生类 C++【英文标题】:Derived Classes C++ 【发布时间】:2012-10-25 19:55:55 【问题描述】:

我正在开发一款基于文本的有趣游戏,但我正在努力解决继承问题 来自基类。我有我的基类Being,它包含所有统计信息 我创造的任何角色。然后我有一个我想参加的课程Combat 来自Being 的所有统计数据(或者来自一个存在并将其传递到战斗中?)并执行 所有战斗的东西。但我不太了解继承,或者至少 如何在Main 中声明函数以使其工作。如果我继续攻击 Being 中的函数,我可以在 main 中写这行:

human.attack(monster);

但是将战斗拆分到另一个班级后,我不知道该怎么写 这主要是它的工作原理。请并感谢您的帮助!

class Being // Base Class

public:

    string name, nameSpecialAttack; // Implement a special attack feature,
                                    // that has a specific mutliplier #
                                    // unique to each being
    int attackBonus, attackMod; // was a float attackMod method for casting
                                // spells that double or halve a Being’s
                                // attack power.
    int baseDamage; // base damage
    int health, healthMax; // current health and max health
    int mp, mpMax; // current mp and max mp
    int arrows; // change to [ranged?] ammo

    Being(); // Default Constructor
    Being(string name, string nameSpecialAttack, int attackBonus,
          int attackMod, int baseDamage, int health, int healthMax,
          int mp, int mpMax, int arrows); // Constructor 2
    // All my set and get functions

然后是我的派生类:

class Combat : public Being

private:

public:

    void attack(Being& target);

;

战斗.cpp:

void Combat::attack(Being& target)

    //unsigned seed = time(0);
    //srand(seed); 
    // Rand # 0-99, * damage+1, /100, * attackMod, parse to int.
    int damage = (int)(attackMod*( ( (rand()%100)*(baseDamage+1) /100) + attackBonus + (rand()%2))); 
    target.health -=damage;

    cout << name << " attacks " << target.name << " doing " << damage << " damage!" << endl;
    cout << target.name << "'s health: " << target.health << endl;

    // Use getHealth() instead and put this function there
    if(target.health <= 0)
    
        cout << endl << name << " killed " << target.name << "! You have won the game! " << endl << endl;
        cout << "Terminating AMnew World, Good Bye.\n" << endl << endl;
        exit(0);
    

主要:

Being human("", "FirstofFurry", 2, 1, 2, 50, 50, 20, 30, 7); // A thing of
                                                             // class Being
Being monster("Armored Goblin", "Rawr", 2, 1, 2, 65, 59, 20, 20, 6);

int main()

    human.attack(monster); // No longer works since attack is in
                           // combat class now
    Sleep(3000);
    cout << endl << endl;
    monster.attack(human);

【问题讨论】:

这应该不是继承关系。你会说“战斗”是一种“存在”吗?我对此表示怀疑。 我觉得“战斗”是“可以进入战斗的东西”的缩写。 是的,我觉得Combat类在这里没用,方法可以在Being中 @FredLarson 我不知道为什么我忘记了这个基本原则。谢谢大家让我直截了当,当我不再那样想时,这让事情变得容易多了。 【参考方案1】:

这不会是你想要继承的东西,战斗不会是一种存在。例如,苹果是一种水果,因此水果基类和苹果派生类在逻辑上是正确的。我建议创建一个 Enemy 类和一个 Hero 类,从敌人身上衍生出僵尸和忍者等怪物。

#include <iostream>
#include <cmath>
#include <string>
using namespace std;

class Character

    public:
    Character()     //does nothing, just represents the heros class
;

class Enemy

    private:
        int Health;         //base class variables
        int WeaponID;
    public:
        Enemy(int hp, int wpID);
        virtual void Attack(Character& Target); //if all monsters have same attack, no need for virtual
        //etc...etc...
;

class Zombie:public Enemy               //DERIVED CLASS, uses base class attack method

    public:
        Zombie(int hp, int wpID):
            Enemy(hp,wpID)
        
;

class Ninja: public Enemy               //DERIVED CLASS, uses its own attack method

    private:
        int NumThrowingKnives;
    public:
        Ninja(int Hp , int ID) : Enemy(Hp,ID)
        
        void Attack(Character& Target); //different attack
        //etc..etc..

;

Enemy::Enemy(int hp, int wpID)

    Health = hp;
    WeaponID = wpID;


void Ninja::Attack(Character& Target)

    cout << "Ninja attack!" << endl;


void Enemy::Attack(Character& Target)

    cout << "Base class attack!" << endl;


int main()

    Character Bob;
    Ninja Bill(50,12);
    Zombie Rob(50,16);
    Bill.Attack(Bob);
    cout << endl;
    Rob.Attack(Bob);



【讨论】:

感谢您发布该代码!现在我知道如何使用您的示例正确地做到这一点,这让一切变得容易多了!我不明白的东西,为什么你的僵尸类和忍者类的构造函数不同?具体来说,这是做什么的: Ninja(int Health , int WeaponID) : Enemy(Health,WeaponID) 每个类都需要一个构造函数,所以忍者和僵尸类调用基构造函数来初始化它的变量。请记住,从另一个类继承的类不能访问它们的私有变量,因此您需要使用基类方法来访问私有变量。【参考方案2】:

您似乎没有正确地利用继承,除非以下情况属实:

在你的游戏中,可以攻击的生物和不能攻击的生物是有区别的。话虽如此,更改继承层次结构可能很有用。

考虑将“类型”设为您继承的内容。

例如:

class Being

public:
    virtual void attack(...) = 0;
;

class Human : public Being

public:
    virtual void attack(...); // Overrides attack in a manner that humans generally would
;

class Goblin : public Being

public:
    virtual void attack(...); // Goblin attack style. This is actually a decent way to handle different types of attacks, as in the special attack in your above definition
;

【讨论】:

不,我不是,我对什么是继承搞混了。其实我还没想过有没有能攻击的生命,不能攻击的生命,我现在要记住了。感谢您展示我应该如何做到这一点!【参考方案3】:

为什么不将human 声明为Combat 类型呢?

Combat human("", "FirstofFurry", 2, 1, 2, 50, 50, 20, 30, 7);

它仍然可以访问Being 的所有公共方法/数据,但也可以使用Combat-only attack 方法。

【讨论】:

以上是关于派生类 C++的主要内容,如果未能解决你的问题,请参考以下文章

关于C++基类、派生类的引用和指针

C++派生类用另一个派生类覆盖基类的成员?

C++中的基类和派生类

C++ 派生类访问属性

获取派生类以显示与派生类的父类具有聚合关系的抽象类中的变量的 C++ 错误

详解C++中基类与派生类的转换以及虚基类