news 2026/5/28 23:11:43

C++ 类的继承、设计与装饰器模式 - 游戏角色示例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++ 类的继承、设计与装饰器模式 - 游戏角色示例

C++ 类继承、设计与装饰器模式 - 游戏角色示例

我将通过一个游戏角色系统来演示C++中的类继承、类设计和装饰器模式。

完整代码示例

#include<iostream>#include<string>#include<memory>#include<vector>// ========== 1. 基类设计:游戏角色 ==========classGameCharacter{protected:std::string name;intlevel;inthealth;intbaseDamage;public:GameCharacter(conststd::string&name,intlevel,inthealth,intbaseDamage):name(name),level(level),health(health),baseDamage(baseDamage){}virtual~GameCharacter()=default;// 虚函数 - 可以在派生类中被重写virtualvoidattack()const{std::cout<<name<<" 发动普通攻击,造成 "<<baseDamage<<" 点伤害!"<<std::endl;}// 虚函数 - 可以在派生类中被重写virtualvoidspecialAbility()const{std::cout<<name<<" 使用了特殊能力!"<<std::endl;}// 非虚函数 - 不希望被重写voidtakeDamage(intdamage){health-=damage;std::cout<<name<<" 受到了 "<<damage<<" 点伤害,剩余生命值: "<<health<<std::endl;}// 纯虚函数 - 派生类必须实现virtualvoiddisplayStats()const=0;voidheal(intamount){health+=amount;std::cout<<name<<" 恢复了 "<<amount<<" 点生命值,当前生命值: "<<health<<std::endl;}std::stringgetName()const{returnname;}intgetLevel()const{returnlevel;}intgetHealth()const{returnhealth;}intgetBaseDamage()const{returnbaseDamage;}voidsetBaseDamage(intdamage){baseDamage=damage;}voidsetHealth(inthp){health=hp;}};// ========== 2. 继承:具体游戏角色类 ==========classWarrior:publicGameCharacter{private:intarmor;intrage;// 战士特有资源:怒气值public:Warrior(conststd::string&name,intlevel,inthealth=150,intbaseDamage=30):GameCharacter(name,level,health,baseDamage),armor(10),rage(0){}// 重写基类的虚函数voidattack()constoverride{std::cout<<name<<" 挥舞巨剑,造成 "<<baseDamage<<" 点物理伤害!"<<std::endl;}// 重写基类的虚函数voidspecialAbility()constoverride{std::cout<<name<<" 使用技能:旋风斩!造成 "<<baseDamage*2<<" 点范围伤害!"<<std::endl;}// 实现基类的纯虚函数voiddisplayStats()constoverride{std::cout<<"=== 战士 ==="<<std::endl;std::cout<<"名称: "<<name<<std::endl;std::cout<<"等级: "<<level<<std::endl;std::cout<<"生命值: "<<health<<std::endl;std::cout<<"基础伤害: "<<baseDamage<<std::endl;std::cout<<"护甲值: "<<armor<<std::endl;std::cout<<"怒气值: "<<rage<<std::endl;}// 战士特有方法voidshieldBash(){std::cout<<name<<" 使用盾击!造成 "<<baseDamage*0.5<<" 点伤害并击晕目标!"<<std::endl;rage+=10;}};classMage:publicGameCharacter{private:intmana;intmaxMana;public:Mage(conststd::string&name,intlevel,inthealth=80,intbaseDamage=20):GameCharacter(name,level,health,baseDamage),mana(100),maxMana(100){}// 重写基类的虚函数voidattack()constoverride{std::cout<<name<<" 发射魔法飞弹,造成 "<<baseDamage<<" 点魔法伤害!"<<std::endl;}// 重写基类的虚函数voidspecialAbility()constoverride{std::cout<<name<<" 使用技能:火球术!消耗30法力,造成 "<<baseDamage*3<<" 点火焰伤害!"<<std::endl;}// 实现基类的纯虚函数voiddisplayStats()constoverride{std::cout<<"=== 法师 ==="<<std::endl;std::cout<<"名称: "<<name<<std::endl;std::cout<<"等级: "<<level<<std::endl;std::cout<<"生命值: "<<health<<std::endl;std::cout<<"基础伤害: "<<baseDamage<<std::endl;std::cout<<"法力值: "<<mana<<"/"<<maxMana<<std::endl;}// 法师特有方法voidcastFireball(){if(mana>=30){mana-=30;std::cout<<name<<" 施放火球术!造成 "<<baseDamage*3<<" 点火焰伤害!"<<std::endl;}else{std::cout<<name<<" 法力值不足!"<<std::endl;}}voidmeditate(){mana=maxMana;std::cout<<name<<" 进行冥想,恢复了全部法力值!"<<std::endl;}};// ========== 3. 装饰器模式:游戏角色装备/状态装饰器 ==========// 装饰器基类classCharacterDecorator:publicGameCharacter{protected:std::shared_ptr<GameCharacter>decoratedCharacter;public:CharacterDecorator(std::shared_ptr<GameCharacter>character):GameCharacter(character->getName(),character->getLevel(),character->getHealth(),character->getBaseDamage()),decoratedCharacter(character){}// 默认转发所有方法到被装饰的角色voidattack()constoverride{decoratedCharacter->attack();}voidspecialAbility()constoverride{decoratedCharacter->specialAbility();}voiddisplayStats()constoverride{decoratedCharacter->displayStats();}voidtakeDamage(intdamage)override{decoratedCharacter->takeDamage(damage);}};// 具体装饰器:武器装饰器classWeaponDecorator:publicCharacterDecorator{private:std::string weaponName;intweaponDamage;public:WeaponDecorator(std::shared_ptr<GameCharacter>character,conststd::string&weaponName,intweaponDamage):CharacterDecorator(character),weaponName(weaponName),weaponDamage(weaponDamage){}voidattack()constoverride{std::cout<<decoratedCharacter->getName()<<" 使用 "<<weaponName<<" 进行攻击,额外造成 "<<weaponDamage<<" 点伤害!"<<std::endl;decoratedCharacter->attack();}voiddisplayStats()constoverride{decoratedCharacter->displayStats();std::cout<<"装备: "<<weaponName<<" (+"<<weaponDamage<<" 攻击力)"<<std::endl;}intgetBaseDamage()const{returndecoratedCharacter->getBaseDamage()+weaponDamage;}};// 具体装饰器:护甲装饰器classArmorDecorator:publicCharacterDecorator{private:std::string armorName;intarmorDefense;public:ArmorDecorator(std::shared_ptr<GameCharacter>character,conststd::string&armorName,intarmorDefense):CharacterDecorator(character),armorName(armorName),armorDefense(armorDefense){}voidtakeDamage(intdamage)override{intreducedDamage=damage-armorDefense;if(reducedDamage<0)reducedDamage=0;std::cout<<armorName<<" 吸收了 "<<armorDefense<<" 点伤害!"<<std::endl;decoratedCharacter->takeDamage(reducedDamage);}voiddisplayStats()constoverride{decoratedCharacter->displayStats();std::cout<<"护甲: "<<armorName<<" (+"<<armorDefense<<" 防御)"<<std::endl;}};// 具体装饰器:状态效果装饰器(如中毒)classPoisonEffectDecorator:publicCharacterDecorator{private:intpoisonDamagePerTurn;intturnsRemaining;public:PoisonEffectDecorator(std::shared_ptr<GameCharacter>character,intpoisonDamage,intduration):CharacterDecorator(character),poisonDamagePerTurn(poisonDamage),turnsRemaining(duration){}voidattack()constoverride{std::cout<<decoratedCharacter->getName()<<" 在中毒状态下攻击,效果减弱!"<<std::endl;// 中毒时攻击力减半autononConstChar=std::const_pointer_cast<GameCharacter>(decoratedCharacter);intoriginalDamage=nonConstChar->getBaseDamage();nonConstChar->setBaseDamage(originalDamage/2);decoratedCharacter->attack();nonConstChar->setBaseDamage(originalDamage);}voidtakeDamage(intdamage)override{// 中毒状态下受到额外伤害std::cout<<decoratedCharacter->getName()<<" 因中毒额外受到 "<<poisonDamagePerTurn<<" 点伤害!"<<std::endl;decoratedCharacter->takeDamage(damage+poisonDamagePerTurn);turnsRemaining--;if(turnsRemaining<=0){std::cout<<decoratedCharacter->getName()<<" 的中毒效果结束了!"<<std::endl;}}voiddisplayStats()constoverride{decoratedCharacter->displayStats();std::cout<<"状态: 中毒 (剩余"<<turnsRemaining<<"回合,每回合受到"<<poisonDamagePerTurn<<"点伤害)"<<std::endl;}};// ========== 4. 使用示例和测试 ==========intmain(){std::cout<<"========== 游戏角色系统演示 =========="<<std::endl<<std::endl;// 创建基础角色std::cout<<"1. 创建基础角色:"<<std::endl;autowarrior=std::make_shared<Warrior>("阿尔萨斯",10);automage=std::make_shared<Mage>("吉安娜",8);warrior->displayStats();warrior->attack();warrior->specialAbility();std::cout<<std::endl;mage->displayStats();mage->attack();mage->specialAbility();std::cout<<std::endl;// 使用装饰器为角色添加装备std::cout<<"2. 为战士添加装备:"<<std::endl;autowarriorWithSword=std::make_shared<WeaponDecorator>(warrior,"霜之哀伤",25);autowarriorWithArmor=std::make_shared<ArmorDecorator>(warriorWithSword,"板甲",15);warriorWithArmor->displayStats();warriorWithArmor->attack();warriorWithArmor->takeDamage(50);std::cout<<std::endl;// 为法师添加装备和状态效果std::cout<<"3. 为法师添加装备和状态效果:"<<std::endl;automageWithStaff=std::make_shared<WeaponDecorator>(mage,"埃提耶什",20);autopoisonedMage=std::make_shared<PoisonEffectDecorator>(mageWithStaff,5,3);poisonedMage->displayStats();poisonedMage->attack();poisonedMage->takeDamage(20);poisonedMage->takeDamage(15);std::cout<<std::endl;// 多层装饰器嵌套std::cout<<"4. 多层装饰器嵌套(完全装备的战士):"<<std::endl;autofullyEquippedWarrior=std::make_shared<ArmorDecorator>(std::make_shared<WeaponDecorator>(warrior,"炎魔之手",35),"巨龙之鳞",20);fullyEquippedWarrior->displayStats();fullyEquippedWarrior->attack();fullyEquippedWarrior->takeDamage(60);std::cout<<std::endl;// 演示多态性std::cout<<"5. 多态性演示(角色集合):"<<std::endl;std::vector<std::shared_ptr<GameCharacter>>characters;characters.push_back(warrior);characters.push_back(mage);characters.push_back(warriorWithArmor);characters.push_back(poisonedMage);characters.push_back(fullyEquippedWarrior);for(constauto&character:characters){std::cout<<"--- "<<character->getName()<<" ---"<<std::endl;character->attack();character->displayStats();std::cout<<std::endl;}// 演示动态添加/移除装饰器std::cout<<"6. 动态添加装饰器(战士获得新武器):"<<std::endl;warrior->displayStats();warrior->attack();autowarriorWithNewWeapon=std::make_shared<WeaponDecorator>(warrior,"萨弗拉斯",40);warriorWithNewWeapon->displayStats();warriorWithNewWeapon->attack();return0;}

关键概念解释

  1. 类继承

· 基类 GameCharacter: 定义了所有游戏角色的通用属性和方法
· 派生类 Warrior 和 Mage: 继承基类并添加职业特有属性和方法
· 虚函数和纯虚函数: 实现多态行为

  1. 类设计原则

· 封装: 将数据成员设为私有/受保护,通过公共接口访问
· 单一职责: 每个类有明确的职责
· 开闭原则: 对扩展开放,对修改关闭

  1. 装饰器模式

· 装饰器基类 CharacterDecorator: 继承自 GameCharacter,包含指向被装饰对象的指针
· 具体装饰器: 添加特定功能而不修改原有类
· 动态组合: 可以在运行时动态添加或移除功能

编译和运行

# 使用g++编译g++-std=c++11-ogame_characters game_characters.cpp# 运行程序./game_characters

输出示例

程序将展示:

  1. 基础角色的创建和使用
  2. 通过继承实现的不同职业
  3. 装饰器为角色动态添加装备和状态效果
  4. 多层装饰器嵌套
  5. 多态性的实际应用

这个示例完整展示了C++中类继承、设计和装饰器模式的实际应用,通过游戏角色系统使概念更加直观易懂。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 23:11:34

GKD订阅配置完整教程:从零开始快速上手第三方订阅管理

GKD订阅配置完整教程&#xff1a;从零开始快速上手第三方订阅管理 【免费下载链接】GKD_THS_List GKD第三方订阅收录名单 项目地址: https://gitcode.com/gh_mirrors/gk/GKD_THS_List 想要高效使用GKD订阅功能&#xff0c;但面对众多订阅源不知如何选择&#xff1f;本教…

作者头像 李华
网站建设 2026/5/20 7:31:53

高校教务|基于Java+ vue高校教务系统(源码+数据库+文档)

高校教务 目录 基于springboot vue高校教务系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 基于springboot vue高校教务系统 一、前言 博主介绍&#xff1a;✌️大…

作者头像 李华
网站建设 2026/5/24 19:47:33

A/B测试在功能验证中的工程化实践与创新

当传统测试遇到体验经济 在敏捷开发与持续交付成为主流的今天&#xff0c;软件测试正经历从“缺陷检测”到“价值验证”的范式转移。传统的功能测试虽能保障基础质量&#xff0c;却难以量化用户对功能的接受度与体验偏好。A/B测试通过科学的对比实验&#xff0c;将主观体验转化…

作者头像 李华
网站建设 2026/5/27 5:58:12

Triton多端口监控终极指南:从零搭建全链路可观测体系

Triton多端口监控终极指南&#xff1a;从零搭建全链路可观测体系 【免费下载链接】server The Triton Inference Server provides an optimized cloud and edge inferencing solution. 项目地址: https://gitcode.com/gh_mirrors/server/server Triton Inference Server…

作者头像 李华
网站建设 2026/5/28 3:39:46

深入解析Matplotlib Figure API:超越`plt.plot()`的图形架构艺术

深入解析Matplotlib Figure API&#xff1a;超越plt.plot()的图形架构艺术 引言&#xff1a;为什么需要深入理解Figure API&#xff1f; 对于大多数Python数据科学家和工程师而言&#xff0c;使用Matplotlib通常从plt.plot()或plt.subplots()开始。然而&#xff0c;当我们面临复…

作者头像 李华