Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;,处理多个构造函数重载和冗余代码 我最近对学习编程有了兴趣,所以我把C++作为一种常用语言。然而,我遇到了一个障碍,我怀疑我的解决方案是否是最好的解决办法。 我有一个相对复杂的类(无论如何对我来说),大约有20个变量,为了简化,这些变量被分为4组。它还有一个在对象初始化期间调用的父类_C++_Class_Object_Constructor_Constructor Overloading - Fatal编程技术网

C++;,处理多个构造函数重载和冗余代码 我最近对学习编程有了兴趣,所以我把C++作为一种常用语言。然而,我遇到了一个障碍,我怀疑我的解决方案是否是最好的解决办法。 我有一个相对复杂的类(无论如何对我来说),大约有20个变量,为了简化,这些变量被分为4组。它还有一个在对象初始化期间调用的父类

C++;,处理多个构造函数重载和冗余代码 我最近对学习编程有了兴趣,所以我把C++作为一种常用语言。然而,我遇到了一个障碍,我怀疑我的解决方案是否是最好的解决办法。 我有一个相对复杂的类(无论如何对我来说),大约有20个变量,为了简化,这些变量被分为4组。它还有一个在对象初始化期间调用的父类,c++,class,object,constructor,constructor-overloading,C++,Class,Object,Constructor,Constructor Overloading,但是,我不需要在所有对象中将这些值设置为默认值以外的值,因此我设置了各种不同的构造函数重载,以考虑所有可能的组合(总共8个构造函数)。因此,为了防止编写重复代码,我编写了一些私有函数,仅在构造函数中调用,它们将变量设置为创建新对象时指定的值 这是解决这个问题的最佳方法吗?我也考虑过将这些变量分组到类或结构中,但感觉这是不必要的复杂,当在各种构造函数重载期间调用相关函数时,应该做到这一点。如果这不是最优的,那么解决这个问题的最佳方法是什么?为什么 我可以对我的问题提供更详细的描述,但这将是一个相当

但是,我不需要在所有对象中将这些值设置为默认值以外的值,因此我设置了各种不同的构造函数重载,以考虑所有可能的组合(总共8个构造函数)。因此,为了防止编写重复代码,我编写了一些私有函数,仅在构造函数中调用,它们将变量设置为创建新对象时指定的值

这是解决这个问题的最佳方法吗?我也考虑过将这些变量分组到类或结构中,但感觉这是不必要的复杂,当在各种构造函数重载期间调用相关函数时,应该做到这一点。如果这不是最优的,那么解决这个问题的最佳方法是什么?为什么

我可以对我的问题提供更详细的描述,但这将是一个相当大的文本墙(我第一次写了这个,但它太失控了)。提前感谢您的投入

根据要求,这里是类定义(武器)。父类(项)已经定义并按预期工作,因此我不会粘贴它,这样人们就不必阅读大量的文本

武器类别定义:

class Weapon: public Item {


public:


    // Default constructor
    Weapon();

    // Full constructor
    Weapon(unsigned GenericID, bool NameFlag, double EquipLoad, double EquipLoadperAmmo, unsigned short ModesNo, Mode* pModes, unsigned short CooldownType, double CooldownDuration, unsigned short CooldownShot, double CooldownPeriod, unsigned short ReloadType, unsigned short ReloadStyle, double ReloadTime, unsigned short MaxMagazine, unsigned short MaxAmmunition, unsigned short StartEnergy, unsigned short MaxEnergy);

    // Constructor for Weapons without Cooldown System
    Weapon(unsigned GenericID, bool NameFlag, double EquipLoad, double EquipLoadperAmmo, unsigned short ModesNo, Mode* pModes, unsigned short ReloadType, unsigned short ReloadStyle, double ReloadTime, unsigned short MaxMagazine, unsigned short MaxAmmunition, unsigned short CurrentEnergy, unsigned short MaxEnergy);

    // Constructor for Weapons without Reload System
    Weapon(unsigned GenericID, bool NameFlag, double EquipLoad, double EquipLoadperAmmo, unsigned short ModesNo, Mode* pModes, unsigned short CooldownType, double CooldownDuration, unsigned short CooldownShot, double CooldownPeriod, unsigned short MaxMagazine, unsigned short MaxAmmunition, unsigned short CurrentEnergy, unsigned short MaxEnergy);

    // Constuctor for Weapons without Energy System
    Weapon(unsigned GenericID, bool NameFlag, double EquipLoad, double EquipLoadperAmmo, unsigned short ModesNo, Mode* pModes, unsigned short CooldownType, double CooldownDuration, unsigned short CooldownShot, double CooldownPeriod, unsigned short ReloadType, unsigned short ReloadStyle, double ReloadTime, unsigned short MaxMagazine, unsigned short MaxAmmunition);

    // Constructor for Weapons without Cooldown nor Reload System
    Weapon(unsigned GenericID, bool NameFlag, double EquipLoad, double EquipLoadperAmmo, unsigned short ModesNo, Mode* pModes, unsigned short MaxMagazine, unsigned short MaxAmmunition, unsigned short CurrentEnergy, unsigned short MaxEnergy);

    // Constructor for Weapons without Cooldown nor Energy System
    Weapon(unsigned GenericID, bool NameFlag, double EquipLoad, double EquipLoadperAmmo, unsigned short ModesNo, Mode* pModes, unsigned short ReloadType, unsigned short ReloadStyle, double ReloadTime, unsigned short MaxMagazine, unsigned short MaxAmmunition);

    // Constructor for Weapons without Reload nor Energy System
    Weapon(unsigned GenericID, bool NameFlag, double EquipLoad, double EquipLoadperAmmo, unsigned short ModesNo, Mode* pModes, unsigned short CooldownType, double CooldownDuration, unsigned short CooldownShot, double CooldownPeriod, unsigned short MaxMagazine, unsigned short MaxAmmunition);

    // Constructor for Weapons without Cooldown, Reload nor Energy System
    Weapon(unsigned GenericID, bool NameFlag, double EquipLoad, double EquipLoadperAmmo, unsigned short ModesNo, Mode* pModes, unsigned short maxMagazine, unsigned short MaxAmmunition);

    ~Weapon();
    void m_print();

    /*Edited public get and set functions for each variable as they are not relevant*/



private:


    // Ubiquitous variables
    unsigned short WepGenericID = 0;
    unsigned short WepVariantID = 0;
    unsigned short WepSkinID = 0;

    double EquipLoad = 0;
    double EquipLoadperAmmo = 0;

    unsigned short ModesNo = 1;
    Mode* pModes = NULL;

    unsigned short MaxAmmunition = 0;
    unsigned short CurrentAmmunition = 0;

    unsigned short MaxMagazine = 0;
    unsigned short CurrentMagazine = 0;


    // Cooldown System variables
    bool WeaponCooldown = false;
    unsigned short CooldownType = 0;
    double CooldownDuration = 0;
    unsigned short CooldownAction = 0;
    double CooldownPeriod = 0;


    // Reload System variables
    unsigned short ReloadType = 0;
    unsigned short ReloadStyle = 0;
    double ReloadTime = 0;


    // Energy System variables
    unsigned short CurrentEnergy = 0;
    unsigned short MaxEnergy = 0;


    //Constructor Auxiliary Functions
    void m_setGeneralWeapon(double EquipLoad, double EquipLoadperAmmo, unsigned short ModesNo, Mode* pModes, unsigned short MaxMagazine, unsigned short MaxAmmunition);
    void m_setCooldownSystem(unsigned short CooldownType, double CooldownDuration, unsigned short CooldownAction, double CooldownPeriod);
    void m_setReloadSystem(unsigned short ReloadType, unsigned short ReloadStyle, double ReloadTime);
    void m_setEnergySystem(unsigned short StartEnergy, unsigned short MaxEnergy);
    void m_setWeaponIDs();
    void m_WepNameDecisionTree();
    string m_searchName();

};
项目父类定义

class Item {


public:

    Item();
    Item(unsigned GenericID);
    Item(unsigned GenericID, bool NameFlag);
    ~Item();
    void m_setCustomName();


private:

    unsigned GenericID = 0;
    unsigned short GenCategoryID = 0;
    unsigned short GenSubCategoryID = 0;

    bool NameFlag = false;
    string ItemName = "Missingno";

    unsigned long InstanceID = 0;

};

为您的子系统创建单独的类

使用生成器/工厂模式创建武器:


你也可以分开弹药,只留下很少的实际成员。通过这种方式,您可以使用更模块化的方法构建所有内容,使您能够更轻松地扩展或修改功能

为您的子系统创建单独的类

使用生成器/工厂模式创建武器:


你也可以分开弹药,只留下很少的实际成员。通过这种方式,您可以使用更模块化的方法构建所有内容,使您能够更轻松地扩展或修改功能

我看到的
武器
API的一个问题是,构造函数使用了大量松散类型的参数,这使得使用它们的代码难以理解和验证。例如,假设您(或您的同事开发人员)使用构造函数API将这一行添加到代码库中:

Weapon bfg(id, true, 3.0, 5.0, 6, modesPtr, COOLDOWN_QUICK, 5.0, 3, 4, RELOAD_SLOW, RELOAD_ANYTIME, 3.8, 12, 14);
读到这一行,很难理解大多数数字的含义。如果一个参数被意外省略,或者其中两个参数的顺序被颠倒,那么(无论是您还是编译器)很可能不会明显地发现那里有bug;相反,在某些游戏测试人员(或客户?)提交错误报告之前,您可能无法发现错误,这是一种昂贵且耗时的发现错误的方法

因此,我建议将必须传递给构造函数的参数数量减少到尽可能少。例如,编写上述内容的另一种方法可能是:

Weapon bfg(id, true);
bfg.SetEquipLoad(3.0);
bfg.SetEquipLoadPerAmmo(5.0);
bfg.SetModes(6, modesPtr);
bfg.SetCooldownType(COOLDOWN_QUICK);
[...]
诚然,这要详细得多(而且确实可能会忘记设置您应该设置的内容),但至少当您查看它时,很明显,
3.0
适用于
equalload
设置,
5.0
适用于
equalLoadPerammo
设置,而不是相反。i、 e.您不必在.h文件和代码之间来回查看,以试图找出每个值所指的内容

请注意,每个集合方法都应采用产生有用结果所需的所有参数;因此,例如,如果在不同时指定
equiloadperammo
的情况下指定
equiloadperammo
没有任何意义,那么您也可以通过单个调用来设置这两个值:

bfg.SetEquipLoadAndEquipLoadPerAmmo(3.0, 5.0);
。。。因此,编码器不可能(即编译时错误)错误地设置一个而忽略设置另一个

至于处理冗余代码的详细性,下一步是将上述代码封装在一个函数中,以便对于任何给定的武器类型,只有一个地方创建它,例如:

Weapon MakeBFG(unsigned id)
{
   Weapon bfg(id, true);
   bfg.SetEquipLoad(3.0);
   bfg.SetEquipLoadPerAmmo(5.0);
   bfg.SetModes(6, modesPtr);
   bfg.SetCooldownType(COOLDOWN_QUICK);
   [...]
   return bfg;
}
现在剩下的代码只需调用
武器bfg=MakeBFG(idCounter++)当它想要创建一个新的BFG枪时


除此之外,我同意另一张海报——您的类似乎正在处理许多不同的事情,如果您能够找到一种方法将其分解为多个较小的类(并非所有的类都需要通过公共API公开;私有类非常好),这可能会帮助您管理代码的总体复杂性;如果您认为将来还想继续添加新功能/行为,那么这样做尤其有益,因为如果您将所有内容都集中在一个类中,当您试图使该类支持越来越多的不同行为/用例时,该类的复杂性将很快失控。

我看到发布的
武器
API的一个问题是,构造函数使用了大量松散类型的参数,这使得使用它们的代码难以理解和验证。例如,假设您(或您的同事开发人员)使用构造函数API将这一行添加到代码库中:

Weapon bfg(id, true, 3.0, 5.0, 6, modesPtr, COOLDOWN_QUICK, 5.0, 3, 4, RELOAD_SLOW, RELOAD_ANYTIME, 3.8, 12, 14);
读到这一行,很难理解大多数数字的含义。如果一个参数被意外省略,或者其中两个参数的顺序被颠倒,那么它很可能不明显(无论是您还是客户)