正确的方法使基类设置父类
Proper way to make base class setup parent class
我在以下情况下有点挣扎:假设我有一个类"Base",它需要一些信息才能正常工作。因此,我设置了一个带有适当参数的构造函数,例如:
class Base {
public: Base(X x, Y y, Z z);
};
这适用于一般的"base"。但是我想有子类,代表特定的"基",经常使用,并包含设置基类所需的所有信息,例如:
class Derived {
public: Derived() {
X x;
x.addSomeInformation("foo bar");
// ...
// now what?
}
};
这里的问题是,我不能通过初始化列表调用父构造函数(通常是这样做的),因为要传递的参数还不存在。
因此,我觉得我的设计有严重的问题。我可以通过引入一个受保护的默认构造函数和一个模仿普通构造函数的"configure"方法来实现这一点,但我不确定这是否是个好主意(主要是因为这样我不能确保子类实际上调用了"configure"——如果不这样做,就会给我留下一个未正确初始化的基类):
class Base {
public: Base(X x, Y y, Z z) { configure(x, y, z); }
protected: Base() {}
protected: void configure(X x, Y y, Z z);
};
class Derived {
public: Derived() {
X x;
// ...
configure(x, y, z);
}
};
一个人如何以适当的方式处理这种情况?
我的第一个建议是让X
有一个有价值的构造函数,而不是强迫它默认构造:
class Derived {
public: Derived() : Base(X("foo bar"), <blah>) {
}
};
如果这不是一个选项,将X-creation逻辑拆分为另一个函数并使用它:
class Derived {
public: Derived() : Base(make_X(), <blah>) {
}
private: static X make_X() {
X x;
x.addSomeInformation("foo bar");
// Anything else needed.
return x;
}
};
整个configure
(有时称为initialize
)方法概念似乎是可行的。事实上,我自己在过去的游戏开发项目中也遇到过这个问题,我只是使用了类似于你提出的解决方案,而不是让它在未来伤害我。
只要这个类不是某个公共API的一部分(即使它是,真的),您不应该担心如果有人不调用configure
可能发生的问题。如果你真的想的话,你可以通过把参数左右设置为无效值来破坏很多api,但这并不意味着这些api不好。只要确保清楚地记录这个使用模式即可。
你感到不安,因为事实上,人们认为代码的正确性依赖于某个方法必须在某个时间调用另一个方法是不好的。他们是对的,只要这会影响代码的可读性(甚至可能影响性能),而在您的情况下,这是不正确的。具有initialize
(或任何您想要调用它的方法)方法的对象以及构造函数都是而不是的坏做法,并且使用这样的方法实际上是编程中广泛使用的习惯用法。
configure
而弹出的错误都可以在它们引起更大的问题之前被捕获并修复。
另一种选择是重新考虑(如果可能的话)X
, Y
等对象的构建方式,并为这些类的用户(在这种情况下是您)提供更多通过构造函数初始化它们的可能性。将这些对象划分为子组件(如果适用于您的情况)也会有所帮助。
这是以一种非常不同的方式给出的答案,但是您可以检查组合而不是继承。
。派生词"真的"是词根吗?
另一种选择是考虑创建一个工厂方法,它负责完成最终调用构造函数所需的所有工作,并提供所需的参数。(这基本上就是Mark B在他的第二个例子中所展示的。)
或者,有派生修改基。X和底。Y变成它们需要的值,作为这些setter被使用的结果更新了基地建设中应该发生的事情。
听起来隐藏的承包商可能是有益的,这样你就可以强制所有的建设通过一个工厂,总是可以调用product->config之前返回具体的产品创建。
- std::具有相同基类的类的变体
- std::用派生类对象设置,但用gcc8.1设置基类比较器
- 如何使用基类对象设置派生类变量的值
- 在基类和派生类之间正确设置函数的返回
- 为什么我不能为位于基类中的类中的类型设置别名
- 由派生类设置的 constexpr 基类成员
- 虚函数可以设置基类的公共数据成员
- 从Derivered类设置值,同时从基类访问相同的值
- 在C 中,如何将派生类中的私有变量设置为基类的输入值
- 当我在基类中设置受保护的数据时,它会更改派生类中受保护数据的值
- C++派生类的设置属性到从同一基类派生的未知类对象
- C++-填充派生类数据成员,同时设置基类属性值
- 通过将基类强制转换为派生类并设置数据来扩展基类
- 设置具有多个固有性的基类的范例方法
- 如何通过派生类的方法复制来设置基类字段
- 通过转换基类指针来设置派生类字段
- 正确的方法使基类设置父类
- 从派生类对象调用基类函数.派生类构造函数中设置的基类数据成员
- 如何将一个派生类的对象在基类私有空间中设置的值传递给另一个派生类别的对象
- 在基类中设置一些值后,可以设置指向派生类的指针吗?