<!--markdown--># C++面向对象核心Demo:王者荣耀英雄类体系

cpp

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

}

拓展注释

函数重载

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

cpp

void func1(){

cout << “hello”;

}

void func1(int n){

cout << "world";

}

此时调用func1(), 输出hello; 调用func1(3), 输出world。

面向对象中类构造函数的重载也是同理。

多态

多态指的是面向对象编程时,有继承关系的不同对象对同一成员做出不同反应。

编译时多态:主要通过函数、运算符重载实现

运行时多态:主要通过虚函数 + 继承

虚函数

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

cpp

#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. 纯虚函数:子类必须实现,否则无法实例化,调用逻辑同普通虚函数(动态绑定)。