讓我們假設我有一些游戲的類層次結構。像這樣: PhysicalObject是BaseUnit的父級,是BaseArcher的父級等等......并且每個層次結構級別都添加了自己的統計資訊。
任何物理物件 - 具有速度和大小。任何 BaseUnit - 生命值。
我希望它被用作列舉,所以:
enum class PhysicalObjectStats { speed, size };
enum class BaseUnitStats { hitpoints };
當然,BaseArcher 必須包括 PhysicalObject 和 BaseUnit 的統計資訊。如何制作這樣的架構?我試圖以如此簡單的方式實作它,只使用映射和動態多型性,但它沒有編譯(老實說,有一個很好的理由):
https://coliru.stacked-crooked.com/a/8496247abd3e6f41
此外,我嘗試創建一個特定的 StatsHolder 類并且它可以作業,但在所有可能的用例(設定和獲取值)中看起來都很糟糕。實際上,如果不進行向下轉換,我就無法在課堂之外獲得價值:
https://coliru.stacked-crooked.com/a/46f4f4aec6a22c57
此外,我的 stats 可能不僅是int,還有bool和其他一些型別。我嘗試為它們使用 std::variant 并且它作業正常,但我不想考慮它,使用“GetStats()”方法。所以,理想情況下我想要這樣一個界面:
std::shared_ptr<PhysicalObject> unit = std::make_shared<BaseUnit>();
unit->SetValue<int>(PhysicalObjectStats::speed);
std::cout << unit->GetValue<bool>(BaseUnitStats::HasArmor);
這使任務變得更加困難。關于如何以一種好的方式完成的任何建議?
uj5u.com熱心網友回復:
我沒有看到 map 和 enum 的意義,而普通成員似乎可以完成這項作業:
struct PhysicalObject
{
int speed = 0;
int size = 0;
};
struct BaseUnitStats : PhysicalObject
{
// or composition:
// physicalObject PhysicalObject;
int hitpoints = 0;
};
對于您的StatsHolder班級:
template<class StatsEnum>
struct StatsHolder
{
void SetStats(StatsEnum stat, int value) { stats[stat] = value; }
int GetStats(StatsEnum stat) const { return stats.at(stat); }
private:
std::map<StatsEnum, int> stats;
};
派生類必須使用using:
struct BaseUnit : PhysicalObject, StatsHolder<BaseUnitStats> {
using PhysicalObject::GetStats;
using StatsHolder<BaseUnitStats>::GetStats;
using PhysicalObject::SetStats;
using StatsHolder<BaseUnitStats>::SetStats;
BaseUnit() { SetStats(BaseUnitStats::hitpoints, 300); }
};
演示
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/341806.html
