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;}关键概念解释
- 类继承
· 基类 GameCharacter: 定义了所有游戏角色的通用属性和方法
· 派生类 Warrior 和 Mage: 继承基类并添加职业特有属性和方法
· 虚函数和纯虚函数: 实现多态行为
- 类设计原则
· 封装: 将数据成员设为私有/受保护,通过公共接口访问
· 单一职责: 每个类有明确的职责
· 开闭原则: 对扩展开放,对修改关闭
- 装饰器模式
· 装饰器基类 CharacterDecorator: 继承自 GameCharacter,包含指向被装饰对象的指针
· 具体装饰器: 添加特定功能而不修改原有类
· 动态组合: 可以在运行时动态添加或移除功能
编译和运行
# 使用g++编译g++-std=c++11-ogame_characters game_characters.cpp# 运行程序./game_characters输出示例
程序将展示:
- 基础角色的创建和使用
- 通过继承实现的不同职业
- 装饰器为角色动态添加装备和状态效果
- 多层装饰器嵌套
- 多态性的实际应用
这个示例完整展示了C++中类继承、设计和装饰器模式的实际应用,通过游戏角色系统使概念更加直观易懂。