C++面向对象核心Demo:王者荣耀英雄类体系

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

// 英雄基类:包含纯虚函数的抽象类,定义所有英雄的通用属性和行为
class Hero {
private:
    string name;    // 英雄名(私有成员,子类不可直接访问)
    int hp;         // 生命值
    int mana;       // 蓝量
protected:
    string camp;    // 阵营(保护成员,子类可直接访问)
public:
    // 构造函数 实例化类对象的时候自动调用 

    //1、默认构造函数 无参,不写也行,默认就带
    Hero(){

    }

    // 2、重载无参构造,给成员默认值
    // Tips:函数重载
    Hero() : name("未知英雄"), hp(3000), mana(500), camp("无阵营") {
        cout << name << ":默认构造,峡谷新生!" << endl;
    }

    // 3、重载带参构造,传入值并赋给对应成员
    Hero(string n, int h, int m, string c) : name(n), hp(h), mana(m), camp(c) {
        cout << name << ":带参构造,加入" << camp << "阵营!" << endl;
    }

    // 4、复制构造函数:值传递对象时触发,传进来一个同类型对象
    Hero(const Hero& other) : name(other.name), hp(other.hp), mana(other.mana), camp(other.camp) {
        cout << name << ":复制构造,镜像召唤!" << endl;
    }

    // 析构函数:类对象销毁时自动执行,一般用于释放动态申请的内存,防止内存泄漏。
    // 虚析构函数:保证基类指针释放派生类对象时析构完整
    // Tips:虚函数
    virtual ~Hero() {
        cout << name << ":退出峡谷,析构销毁!" << endl;
    }

    // 普通成员函数:设置/获取私有属性
    void setName(string n) { name = n; }
    string getName() const { return name; }
    int getHp() const { return hp; }

    // 运算符重载:重载[],通过下标访问英雄属性
    string operator[](int index) const {
        if (index == 0) return name;
        else if (index == 1) return to_string(hp);
        else if (index == 2) return camp;
        else return "无效属性索引";
    }

    // 虚函数:英雄普通攻击(子类可重写,实现不同普攻效果)
    virtual void normalAttack() const {
        cout << name << ":基础普攻,造成物理伤害!" << endl;
    }

    // 纯虚函数:英雄核心技能(抽象行为,子类必须实现)
    virtual void coreSkill() const = 0;

    //--------------静态 static-------------------------
    // 静态成员可不通过对象,直接 类名::成员名访问,所有类对象共享这一个

    // 静态成员:属于类,所有英雄共享的峡谷属性,
    static string gameName;
    // 静态成员函数:打印游戏信息,属于类可通过对象/类名调用
    static void showGameInfo() {
        cout << "当前游戏:" << gameName << " | 5v5峡谷对战" << endl;
    }

    // 单参构造:实现自动类型转换(字符串直接转为英雄名)
    Hero(string n) : name(n), hp(3000), mana(500), camp("无阵营") {
        cout << name << ":单参构造,快速创建!" << endl;
    }
};

// 静态成员变量:类外初始化
string Hero::gameName = "王者荣耀";

// 派生类:射手英雄(公有继承英雄基类)
class Archer : public Hero {
private:
    int attackRange; // 射手专属:攻击射程
    static int archerCount; // 静态计数:当前峡谷射手数量
public:
    // 派生类无参构造:必须显式调用基类构造
    Archer() : Hero("鲁班七号", 3500, 400, "射手"), attackRange(800) {
        archerCount++;
        cout << getName() << ":射手构造,射程" << attackRange << "!" << endl;
    }
    // 带参构造
    Archer(string n, int h, int m, string c, int r) : Hero(n, h, m, c), attackRange(r) {
        archerCount++;
        cout << getName() << ":射手构造,射程" << attackRange << "!" << endl;
    }

    // 派生类析构:自动调用基类析构
    ~Archer() override {
        archerCount--;
        cout << getName() << ":射手析构,峡谷射手数量-1!" << endl;
    }

    // 重写基类虚函数:射手专属普攻
    void normalAttack() const override {
        cout << getName() << ":射手普攻,远程物理伤害,射程" << attackRange << "!" << endl;
    }

    // 实现基类纯虚函数:射手核心技能
    void coreSkill() const override {
        cout << getName() << ":核心技能-无敌鲨嘴炮,超远程范围伤害!" << endl;
    }

    // 静态成员函数:获取当前峡谷射手数量
    static int getArcherCount() {
        return archerCount;
    }
};

// 射手静态计数初始化
int Archer::archerCount = 0;

// 派生类:法师英雄(公有继承英雄基类)
class Mage : public Hero {
private:
    int magicPower; // 法师专属:法术强度
public:
    // 派生类构造:调用基类构造 无参,默认填充妲己信息
    Mage() : Hero("妲己", 3000, 800, "法师"), magicPower(600) {
        cout << getName() << ":法师构造,法强" << magicPower << "!" << endl;
    }

    Mage(string n, int h, int m, string c, int mp) : Hero(n, h, m, c), magicPower(mp) {
        cout << getName() << ":法师构造,法强" << magicPower << "!" << endl;
    }

    // 重写基类虚函数:法师专属普攻
    void normalAttack() const override {
        cout << getName() << ":法师普攻,远程法术伤害,法强" << magicPower << "!" << endl;
    }

    // 实现基类纯虚函数:法师核心技能
    void coreSkill() const override {
        cout << getName() << ":核心技能-灵魂冲击,单体高额法术伤害!" << endl;
    }
};

// 测试函数:基类指针/引用传参,实现多态
// 基类指针作形参,可传入任意派生类对象
void heroFight(Hero* hero) {
    cout << "\n【峡谷对战】" << endl;
    hero->normalAttack();
    hero->coreSkill();
}

// 引用传递:不触发复制构造函数
void heroInfo(const Hero& hero) {
    cout << "\n【英雄信息】" << endl;
    cout << "姓名:" << hero[0] << " | 生命值:" << hero[1] << " | 阵营:" << hero[2] << endl;
}

// 值传递:触发复制构造函数
void heroCopy(Hero hero) {
    cout << "\n【复制英雄】" << endl;
    hero.normalAttack();
}

// 主函数:测试所有面向对象特性
int main() {
    // 静态成员测试:类名/对象均可调用静态函数
    cout << "===== 峡谷初始化 =====" << endl;
    Hero::showGameInfo(); // 静态成员调用
    Archer luBan; // 实例化射手鲁班
    luBan.showGameInfo();
    cout << "当前峡谷射手数量:" << Archer::getArcherCount() << endl;

    // 继承与构造测试:派生类构造自动调用基类构造
    cout << "\n===== 召唤英雄 =====" << endl;
    Mage daJi; // 实例化法师对象
    Archer houYi("后羿", 3800, 450, "射手", 900); //实例化射手对象
    // 单参构造实现自动类型转换
    Hero yase = "亚瑟";

    // 多态测试:基类指针指向派生类对象
    cout << "\n===== 峡谷对战 =====" << endl;
    Hero* hero1 = &luBan;
    Hero* hero2 = &daJi;
    heroFight(hero1);
    heroFight(hero2);

    // 运算符重载测试:[]访问英雄属性
    cout << "\n===== 英雄属性查询 =====" << endl;
    heroInfo(houYi);

    // 复制构造测试:引用传递vs值传递
    cout << "\n===== 英雄复制 =====" << endl;
    heroInfo(luBan);    // 引用传递,不触发复制构造
    heroCopy(luBan);    // 值传递,触发复制构造

    // 动态申请对象:虚析构测试
    cout << "\n===== 远程召唤英雄 =====" << endl;
    Hero* hero3 = new Archer("伽罗", 3600, 500, "射手", 1000);
    heroFight(hero3);
    delete hero3; // 虚析构保证派生类+基类均析构

    cout << "\n===== 峡谷闭营 =====" << endl;
    cout << "当前峡谷剩余射手数量:" << Archer::getArcherCount() << endl;

    return 0;
}

拓展注释

函数重载

同一变量名,利用参数的类型或个数不同确定实际调用哪一个

void func1(){
    cout << “hello”;
}
void func1(int n){
    cout << "world";
}

此时调用func1(), 输出hello; 调用func1(3), 输出world。
面向对象中类构造函数的重载也是同理。

多态

多态指的是面向对象编程时,有继承关系的不同对象对同一成员做出不同反应。
编译时多态:主要通过函数、运算符重载实现
运行时多态:主要通过虚函数 + 继承

虚函数

基类声明对象时加 virtual 前缀,主要用于基类指针指向子类对象时,非需函数调用的还是基类版本,而虚函数的话就可以正确调用重载版本

#include <iostream>
using namespace std;

class Hero {
public:
    // 1. 非虚函数:静态绑定,子类无法多态重写
    void normalFunc() { 
        cout << "Hero-非虚函数(基础行为)" << endl; 
    }

    // 2. 普通虚函数:动态绑定,子类可选重写
    virtual void virtualFunc() { 
        cout << "Hero-普通虚函数(默认行为)" << endl; 
    }

    // 3. 纯虚函数:动态绑定,子类必须重写(无默认实现)
    virtual void pureVirtualFunc() = 0;
};

// 派生类:实现纯虚函数,重写普通虚函数,不处理非虚函数
class Archer : public Hero {
public:
    // 重写普通虚函数(可选)
    void virtualFunc() override { 
        cout << "Archer-重写普通虚函数(射手专属行为)" << endl; 
    }

    // 必须重写纯虚函数(否则Archer是抽象类,无法实例化)
    void pureVirtualFunc() override { 
        cout << "Archer-实现纯虚函数(射手核心技能)" << endl; 
    }

    // 子类同名非虚函数:仅隐藏基类版本,无多态
    void normalFunc() { 
        cout << "Archer-隐藏基类非虚函数" << endl; 
    }
};

int main() {
    Hero* p = new Archer(); // 基类指针指向子类对象
    
    // 1. 非虚函数:静态绑定,执行基类版本
    p->normalFunc();        
    // 2. 普通虚函数:动态绑定,执行子类重写版本
    p->virtualFunc();       
    // 3. 纯虚函数:动态绑定,执行子类实现版本
    p->pureVirtualFunc();   

    delete p;
    return 0;
}

输出结果(核心对比)

Hero-非虚函数(基础行为)
Archer-重写普通虚函数(射手专属行为)
Archer-实现纯虚函数(射手核心技能)

核心总结(3个关键点)

  1. 非虚函数:基类指针调用时,只看指针类型(Hero*),永远执行基类版本;
  2. 普通虚函数:基类指针调用时,看实际对象类型(Archer),执行子类重写版本(子类可选不重写,用基类默认);
  3. 纯虚函数:子类必须实现,否则无法实例化,调用逻辑同普通虚函数(动态绑定)。

标签: none

评论已关闭