如何避免在C++中的派生类中重复基类构造函数参数
How to avoid repeating base class constructor parameters in derived class in C++?
我有以下类的层次结构:
class Human {
void foo()=0; //abstract
int age;
bool sex;
double size;
Human(int pAge,bool pSex,double pSize) : age(pAge), sex(pSex), size(pSize)
}
class MetaHuman : Human { //abstract
double power;
bool fly;
bool heal;
MetaHuman(int pAge,bool pSex,double pSize,double pPower,bool pFly,bool pHeal) : Human(...), power(pPower),fly(pFly),heal(pHeal) }
class SuperHuman : MetaHuman {
void foo() const {}; //non abstract
bool xray;
bool inspace;
double teleportation;
SuperHuman(int pAge,bool pSex,double pSize,double pPower,bool pFly,bool pHeal,bool pXray,bool pInspace,double pTeleportation) :
MetaHuman(...),xray(pXray),inspace(pInspace),teleportation(pTeleportation)
}
正如你所看到的,我只是在每个派生类中重复基类构造函数的所有参数,并添加相对于派生类的几个参数。
有什么方法/模式/设计可以避免像这样重写所有内容吗?
当涉及到严格的OOP时,这些问题通常通过将参数封装在structs:中来处理
struct HumanData {
int pAge,
bool pSex,
double pSize,
double pPower,
bool pFly,
bool pHeal
}
或者,你可以制作一个结构,在MetaHuman的基础上创建一个超人。
只是一个提示,因为我看到你正在尝试一些游戏开发。通常将属性包装在结构中,"会得到很多回报"。所以,让你的SEX成为一个基于布尔的枚举(我知道,有点过头了:)。您可以在此处阅读C++0x中基于类的枚举:https://smartbear.com/blog/closer-to-perfection-get-to-know-c11-scoped-and-ba/?feed=develop
您将获得额外的强类型类数据,几乎不会对性能产生影响。
顺便说一句:你绝对确定你需要让你的阶级等级制度如此陡峭吗?正如斯特劳斯特鲁普所说的";不要立即为你的所有类创建一个独特的基础。通常,对于许多/大多数类来说,没有它可以做得更好"-这是非常准确的。
C++不是C#/Java——强迫它这样做只会让它反叛。
如果你的问题是参数的数量太多,你可以用structs来减少。创建一个名为humanData的结构,该结构包含年龄、性别等字段,并询问其余字段。然后派生的构造函数将如下所示:
MetaHuman(humanData, metaHumanData)
如果你喜欢这个并想更进一步,你甚至可以让humanData成为metaHumanData的成员。
实际上,您需要这些值来完全定义SuperHuman。如果你想在同一个MetaHuman上创建更多的超人,你可以创建一个默认的MetaHuman,在MetaHuman中实现复制构造函数(无论如何你都应该这样做),然后做一些类似的事情
SuperHuman(specific parameters) : MetaHuman(normalHuman), xray(...), etc
或
SuperHuman(MetaHuman normalHumanBeforeMutation, <specific params>): MetaHuman(normalHumanBeforeMutation), ...
简单的答案是否定的。
如果您希望能够使用xray
和sex
创建SuperHuman
,那么您必须能够将这两者传递到构造函数中。
如果限制构造函数参数非常重要,那么有两个选项可供选择:
SuperHuman(int pAge = 0, bool pSex = false, double pSize = 0.0, double pPower = 0.0, bool pFly = false, bool pHeal = false, bool pXray = false, bool pInspace = false, double pTeleportation = 0.0)
默认构造函数意味着您只需要将参数传递到要发送的最后一个非默认参数,因此:
SuperHuman SuperMan(29, true, 225, numeric_limits<double>::infinity(), true, true, true); //pInspace = false and pTeleportation = 0.0
您还可以创建一个构造函数,该构造函数接受父对象,并为以后的初始化默认所有其他值:
SuperHuman(const MetaHuman& pMetaHuman) : MetaHuman(pMetaHuman), xray(false), inspace(false), teleportation(0.0){}
请注意,第二个方法意味着您可能无法使用该构造函数获得const SuperHuman
。
- 如何使基类的运算符对基类的可变参数数可见(请参阅下面的代码)?
- 命名参数习惯用法和(抽象)基类
- C++重载函数,一个采用基类的参数,另一个采用派生类的参数
- 如何允许模板参数中的类类型,仅当它有两个基类时
- 为什么我需要在成员发起器列表中重复基类的模板参数?
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- C++17 使用驱动类常量作为基类构造函数的参数来初始化基类构造函数
- 根据参数数调用 mixin 基类的构造函数
- 派生类(构造函数具有参数)和基类(构造函数缺少参数)之间没有可行的转换
- 如何将子类作为函数的参数传递给期望基类,然后将该对象传递到指向这些抽象类对象的指针向量中?
- 在C++单元测试上下文中,抽象基类是否应将其他抽象基类作为函数参数
- C++ 如何使派生类自动获取基类参数
- 将派生类作为参数传递给方法,该方法是具有智能指针的基类
- 将函数上调整到基类参数的另一个
- 将派生类对象传递给具有 C++ 中基类参数的函数时,为什么要传递引用而不是值?
- 如何使用派生类中的虚拟函数,该函数在另一个具有基类参数的类中声明
- 将基类 2 参数构造函数调用到子类 1 参数构造函数中
- 指向友元函数中基类参数类型的指针
- 按值传递共享指针并接受作为基类参数是如何工作的
- 为带有基类参数的派生类参数调用函数重载