改进 13 参数构造函数
Improve on a 13-parameter constructor
感谢Microsoft的Intellisense和Atomineer的Atomineer Utils...所有这些参数都是必需且不可变的。
有没有更好的方法可以做到这一点?
/**************************************************************************************************
* <summary>Initializes a new instance of the ADTBattleCharacter class.</summary>
* <param name="name"> The name of the character.</param>
* <param name="max_HP"> The maximum hit points.</param>
* <param name="max_MP"> The maximum magic power.</param>
* <param name="strength"> The strength.</param>
* <param name="agility"> The agility.</param>
* <param name="attack_power"> The attack power.</param>
* <param name="defense_power">The defense power.</param>
* <param name="gold"> The gold carried by the character.</param>
* <param name="experience"> The experience the character is worth.</param>
* <param name="stop_resist"> The character's resistance to stopspell.</param>
* <param name="sleep_resist"> The character's resistance to sleep.</param>
* <param name="hurt_resist"> The character's resistance to hurt/hurtmore.</param>
* <param name="spell_list"> Available spells.</param>
**************************************************************************************************/
ADTBattleCharacter(std::string name, unsigned char max_HP, unsigned char max_MP,
unsigned char strength, unsigned char agility,
unsigned char attack_power, unsigned char defense_power,
unsigned short gold, unsigned short experience,
double stop_resist, double sleep_resist, double hurt_resist,
std::bitset<SPELL_MAX> spell_list);
看看你的具体情况,在我看来,你还没有很好地解决问题。
从概念上讲,系统中的角色具有:
- 一个名字。
- 一个属性块,包含他们的基本属性(HP、防御等)。
- 角色的次要属性(经验)。
- 一个库存,其中包括他们当前的法术列表和他们的金币,以及其他可能的东西。
这是 4 个参数,而不是 13 个。当你在编写一个函数时,你看到它需要大量的参数,其中的一些参数在概念上相互链接的可能性很大。其他函数也很有可能希望使用这些链接参数。
例如,您可能希望显示角色的统计信息块。执行此操作的功能真的需要字符吗?不;它只需要统计块。所以它应该需要一个统计块对象。
就像角色的构造函数一样。
更好的方法是使用 Builder 设计模式。或者,更简单地说,您可以向当前构造函数声明一个包含所有参数字段的类。参数类本身可以具有将字段初始化为合理的默认值的构造函数(或构造函数),并且您可以通过直接访问字段来更改值。然后,在参数类中实现一个函数来构造对象,或者定义一个采用参数类实例的对象构造函数。
如果目标只是减少提供给构造函数的参数数量,则有很多方法可以实现这一点。真正的问题是,正如我从评论到我的第一篇文章的理解,是否有更简单的方法来管理参数。
使参数更易于管理的一种方法是使用常规数据结构来维护它们。类似于地图的东西。
enum AttrTag { AT_Name, AT_Max_HP, AT_Max_MP, //...
AT_Spells };
struct Attributes {
typedef std::unique_ptr<AttrBase> AttrPtr;
typedef std::map<AttrTag, AttrPtr> AttrMap;
AttrMap attributes;
template <AttrTag TAG>
typename Attr<TAG>::value_type get_attr () const {
AttrMap::const_iterator i = attributes.find(TAG);
if (i != attributes.end()) return i->second->attr_cast<TAG>()->value;
return Attr<TAG>::default_value;
}
template <AttrTag TAG>
void set_attr (typename Attr<TAG>::value_type value) {
attributes[TAG] = AttrPtr(new Attr<TAG>(value));
}
bool has_attr (AttrTag t) const {
return attributes.find(t) != attributes.end();
}
};
它将像这样使用:
Attributes attrs;
attrs->set_attr<AT_Gold>(100);
//...
ADTBattleCharacter(attrs);
//...
unsigned short g = attrs->get_attr<AT_Gold>();
这些属性将来自知道如何委托给实际属性的AttrBase
类。
template <AttrTag> struct Attr;
struct AttrBase {
virtual ~AttrBase () {}
template <AttrTag TAG> Attr<TAG> * attr_cast () {
return dynamic_cast<Attr<TAG> *>(this);
}
};
属性将通过专用于继承自AttrBase
的Attr
模板来创建。
template <AttrTag TAG>
struct Attr : public AttrBase {
typedef unsigned char value_type;
enum { default_value = 0 };
value_type value;
Attr (value_type v) : value(v) {}
};
template <>
struct Attr<AT_Name> : public AttrBase {
typedef std::string value_type;
static std::string default_value;
value_type value;
Attr (value_type v) : value(v) {}
};
template <>
struct Attr<AT_Gold> : public AttrBase {
typedef unsigned short value_type;
enum { default_value = 1 };
value_type value;
Attr (value_type v) : value(v) {}
};
这允许在不增加构造函数复杂性的情况下以增量方式添加新属性。此外,可以将相同的属性集合传递给不同的实体,并且每个实体只能对它们感兴趣的属性做出反应。只需设置属性的子集。可以测试属性是否存在,也可以使用默认值。如果要添加和删除动态属性,可以通过添加附加映射来扩展容器以保存它们。
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- 在按值调用 (c++) 中转发构造函数参数
- 如何使用 swig 修改类构造函数以保留对其中一个构造函数参数的引用?
- 如何在构造函数参数中初始化"std::set"?
- 何时应在构造函数参数中使用 const C++?
- 使用模板化结构作为构造函数参数
- 使用 lambda 作为构造函数参数是否需要C++ 17?
- 如何使输入文本文件成为构造函数参数?c++
- shared_ptr构造函数参数是否应按值传递
- 是否允许使用初始值设定项列表将const数组引用实例化为构造函数参数
- 复制构造函数参数为0
- 用作成员构造函数参数的函数的求值顺序
- 结构中的默认成员值或默认构造函数参数
- C++将引用成员绑定到构造函数参数
- 如何通过可变参数模板将多个构造函数参数转发到数组初始值设定项列表?
- 模板函数指针参数与构造函数参数
- 如何将 std::string 作为构造函数参数传递,并将其保存的 C 字符串存储在 void 指针中?
- 如何基于构造函数参数模板化类成员函数的代码
- 将派生类构造函数参数传递给受保护的成员
- 如何根据构造函数参数使用超类类型初始化成员变量?