我得到了一个有很多成员的结构。我决定为我的结构编写一些函数,但在函数调用中键入所有成员作为参数感觉不对劲。有什么办法缩短这个吗?
items::items(std::string name_, std::string role_, uint16_t prize_, uint16_t phys_power_, uint16_t mag_power_,
uint16_t attack_speed_, uint16_t life_steal_, uint16_t flat_pen_, uint16_t perc_pen_, uint16_t crit_,
uint16_t phys_prot_, uint16_t mag_prot_, uint16_t cc_red_, uint16_t health_, uint16_t hp5_, uint16_t speed_,
uint16_t cd_red_, uint16_t mana_, uint16_t mp5_) {
name = name_;
role = role_;
prize = prize_;
phys_power = phys_power_;
mag_power = mag_power_;
attack_speed = attack_speed_;
life_steal = life_steal_;
flat_pen = flat_pen_;
perc_pen = perc_pen_;
crit = crit_;
phys_prot = phys_prot_;
mag_prot = mag_prot_;
cc_red = cc_red_;
health = health_;
hp5 = hp5_;
speed = speed_;
mana = mana_;
mp5 = mp5_;
}
void items::print_item(items s) {
std::cout << name << " " << role << " " << prize << " " << phys_power << " " << mag_power << " " << attack_speed << " " << life_steal << " " << flat_pen <<
" " << perc_pen << " " << crit << " " << phys_prot << " " << mag_prot << " " << cc_red << " " << health << " " << hp5 << " " << speed << " " << mana << " " <<
mp5 << std::endl;
}
我们可以使用构建器模式来解决您的问题。我们将为项提供一个非常简单的构造函数,它只将名称作为param。我们将使用构建器模式构建其余的属性。让我们从ItemBuilder和Item结构的正向声明开始。
struct ItemBuilder;
struct Item
{
Item (std::string name_):name (name_)
{
};
static ItemBuilder getBuilder(std::string name_);
std::string name;
std::string role;
uint16_t prize;
uint16_t phys_power;
uint16_t mag_power;
uint16_t attack_speed;
uint16_t life_steal;
uint16_t flat_pen;
uint16_t perc_pen;
uint16_t crit;
uint16_t phys_prot;
uint16_t mag_prot;
uint16_t cc_red;
uint16_t health;
uint16_t hp5;
uint16_t speed;
uint16_t cd_red;
uint16_t mana;
uint16_t mp5;
};
现在让我们编写ItemBuilder。
struct ItemBuilder
{
private:
Item m_item;
public:
ItemBuilder (std::string name_):m_item (name_)
{
}
operator Item () const
{
return std::move (m_item);
};
ItemBuilder & role (std::string role_)
{
m_item.role;
return *this;
};
ItemBuilder & prize (uint16_t prize_)
{
m_item.prize = prize_;
return *this;
};
ItemBuilder & phys_pow (uint16_t phys_power_)
{
m_item.phys_power = phys_power_;
return *this;
};
ItemBuilder & mag_power (uint16_t mag_power_)
{
m_item.mag_power = mag_power_;
return *this;
};
ItemBuilder & attack_speed (uint16_t attack_speed_)
{
m_item.attack_speed = attack_speed_;
return *this;
};
ItemBuilder & life_steal (uint16_t life_steal_)
{
m_item.life_steal = life_steal_;
return *this;
};
ItemBuilder & flat_pen (uint16_t flat_pen_)
{
m_item.flat_pen = flat_pen_;
return *this;
};
};
最后,我们不应该忘记Item::getBuilder
ItemBuilder项::getBuilder(std::string name_({return ItemBuilder(name_(;}
int
main ()
{
auto builder = Item::getBuilder("any");
Item it = builder.role("mage").phys_pow(1).attack_speed(2).mag_power(100);
std::cout << it.name << " " << it.phys_power << " " << it.attack_speed << " " << it.mag_power;
return 0;
}
运行代码
有用的链接:
- https://en.wikipedia.org/wiki/Builder_pattern#:~:text=%20builder%20pattern%20is%20a,Gang%20of%20Four%20design%20pattern
- https://refactoring.guru/design-patterns/builder/cpp/example
我认为这些是角色,或者是某种游戏中的物品。我假设有有限数量的物品类型(法师、战士、矮人等(,或者可能有很多";家庭";项目,每个项目有几个";子类型";。
编辑:第一步实际上是为成员设置合理的默认值,这样您只需要设置不同的值。在C++11及更高版本中,您可以简单地在成员声明中指定一个默认值,seehttps://en.cppreference.com/w/cpp/language/data_members,可以与适当的构造函数组合。
准备好的值集合的一种可能性是为每个"值"定义一个恒定的原型;类型";使用标准设置。在使用适当的原型初始化之后,每个实例中只需要修改少数成员。
另一种可能性是将你的大结构划分为可以单独设置的子结构:例如,魔法能力、物理能力、当前状况等。这些可以组合起来创建基本项目,然后可以通过将单个属性设置为合适来定制。
划分成更小的子单元也可以通过继承层次结构来实现;但复杂的继承已经失宠,因为它把代码结合得太紧密了。相反,组合似乎会产生更易于理解和维护的代码(这不是几乎一样吗?(。但是,至少可以有几个接口,以便在适当的情况下对项目进行统一处理。
编辑:既然你在评论中提到了:从文本文件中构建项目是个好主意。它允许您在不重新编译的情况下创建多个不同的项实例。我推荐一个非常简单的xml结构,您可以手动解析,也可以使用库(TinyXML2?(解析。或者,你也可以从一个更简单的逗号分隔列表开始(但可能仍然是键/值对,这样你就可以省略一些,并将它们保留为默认值!(,你还可以在Excel(或LibreOffice等(中创建、读取或编辑它