-
魔法少女扩展包
// 前面是include和基类 // ... class InabaMeguru : public MahouShojo { private: std::string name; bool firstTransform = true; // 更清晰的状态标记 public: InabaMeguru() { transformationPhrase = "Ciallo~(∠・ω< )⌒★"; } void transform() override { // 当然,name.empty() 效果是一样的 // 但是这样语义更清晰 if (firstTransform) { std::cout << "Senpai, o namae o oshiete itadakemasu ka?" << std::endl; std::getline(std::cin, name); firstTransform = false; } std::cout << name << ", " << transformationPhrase << std::endl; } }; int main() { // 刻意使用了堆对象 // 当然可以使用InabaMeguru mgr;这样的栈对象 InabaMeguru* mgr = new InabaMeguru; mgr->transform(); mgr->transform(); // 堆对象记得释放 delete mgr; return 0; } -
胰脏物语
#include <iostream> #include <vector> #include<string> using namespace std; class KyoubyouBunko{ private: vector<string>pages; public: KyoubyouBunko():pages{ "20XX/11/29\nI don't want to write dark things, but I must... First, I apologize to my family." "20XX/12/04\nI've decided not to hate my fate. That's why I named this 'Kyoubyou Bunko'." "20XX/10/12\nI started dating someone new. I don't want to tell him about my illness." }{} friend class Best_friend; }; class Best_friend{ public: void read(const KyoubyouBunko& diary){ cout<<"=== Reading KyoubyouBunko ==="<<endl; for(int i = 0; i<diary.pages.size();i++){ cout<<(i+1)<<" page:"<<diary.pages[i]<<endl; } cout<<"============================="<<endl; } void write(KyoubyouBunko& diary, const string& new_page){ diary.pages.push_back(new_page); cout <<"Added new diary page"<<endl; } }; int main(){ KyoubyouBunko diary; Best_friend haruki; haruki.read(diary); haruki.write(diary,"Ordinary words could never capture what you mean to me. \nThe truth is, I want to devour your pancreas!"); haruki.read(diary); return 0; } -
重构
ManaEntity类#include <cstring> // for strcpy class ManaEntity { public: // 普通构造函数 ManaEntity(EntityType t, int h, int m, const string& name) : type(t), HP(h), MP(m), entityName(name) }} // 其实可以不写这个编译器也会默认生成,但是写出来更清楚 ManaEntity(const ManaEntity& other) = default; ManaEntity(ManaEntity&& other) = default; ~ManaEntity() = default; private: EntityType type; int HP; int MP; std::string entityName; };由此可见,“0 原则”可以少造轮子,减少代码,让程序简洁易读。这就是"0原则"的魅力——让编译器和大佬们写的标准库为我们处理复杂的资源管理问题!
-
魔法少女乐队
// 类定义、include语句 // 别忘了vector // ... int main() { vector <MahouShoujo*> mahoushoujo_band; // 又看一集(不是) mahoushoujo_band.push_back(new UnluckyNene); mahoushoujo_band.push_back(new SmartNene); mahoushoujo_band.push_back(new InabaMeguru); // 指针引用:auto* 这样可少拷贝一次 // 当然这里直接auto也没错 for (auto* mahoushoujo : mahoushoujo_band) { mahoushoujo->battle(); } for (auto* mahoushoujo : mahoushoujo_band) { delete mahoushoujo; } return 0; }当然,智能指针可以不用手动释放:
// 使用智能指针,避免手动内存管理 #include <memory> int main() { std::vector<std::unique_ptr<MahouShojo>> mahoushoujo_band; mahoushoujo_band.push_back(std::make_unique<UnluckyNene>()); mahoushoujo_band.push_back(std::make_unique<SmartNene>()); mahoushoujo_band.push_back(std::make_unique<InabaMeguru>()); for (auto& mahoushoujo : mahoushoujo_band) { mahoushoujo->battle(); } // 不需要手动delete,自动释放内存 return 0; }可能的输出:
NeNeNeNeNe! Assault Launched! MP: 100 NeNeNeNeNe Assault Launched! Uhhh...So hot... Toy charging, currently: 10 MP: 70 Senpai, o namae o oshiete itadakemasu ka? [等待用户输入,比如输入: Hoshina Shuuji] Hoshina Shuuji, Ciallo~(∠・ω< )⌒★ Assault Launched! MP: 100通过这个输出可以看到,即使是相同的
battle()接口,每个类的行为也不同UnluckyNene:使用基类的默认行为SmartNene:重写了onanii(),MP损失更少且有额外效果InabaMeguru:重写了transform(),有交互式输入
这完美展示了C++多态性的威力!
丙加·第11章·答案
·391 字·2 分钟·