如果它是安全的,我很感兴趣,在某些条件下将基类的实例向下转换(感谢迈克)到派生类。我认为样本是最简单的解释方法:
struct BaseA
{
void foo() const {}
double bar_member;
// no virtuals here
};
struct DerivedA : public BaseA
{
double bar(double z) {bar_member = z;return bar_member;}
// DerivedA does not add ANY member variables to BaseA.
// It also does not introduce ANY virtual functions.
};
struct BaseB
{
BaseA baseA;
};
// add extra functionality to B, to do this,
// i also need more functionality on baseA.
struct DerivedB : public BaseB
{
// is this "safe"? since BaseA and DerivedA
// should have the same memory layout?!?
DerivedA& getA() {return *static_cast<DerivedA*>(&baseA);}
double foo(double z) {return getA().bar(z);}
};
#include <iostream>
int main(int argc, char** argv)
{
DerivedB b;
// compiles and prints expected result
std::cout << b.foo(argc) << std::endl;
}
在我的例子中,类 BaseA 和 BaseB 实现了某种视图概念。但是,它们还包含在派生类中添加更多功能所需的所有数据成员。我知道我可以实现视图以仅保存对提供功能的类的引用。但是,这会带来一些缺点:
- 我需要重写视图类的整个界面。
- 在我的例子中,派生类拥有一个额外的模板参数(回调类型),我想在视图中删除它。因此,视图不能直接引用提供功能的类。
我测试了我的代码,它可以工作,但是,我并不真正相信这种方法。是的,我知道我可以通过虚拟等实现其中的一些功能,但它确实对性能至关重要......
欢迎任何想法,提示
马丁
对于感兴趣的人:我通过以下方式更改了我的设计:
struct DerivedB : public BaseB
{
// encapsule the required extended functionality of BaseA member
struct OperateOnBaseA
{
OperateOnBaseA(BaseA& a);
double dosomething(double);
};
OperateOnBaseA a_extension;
DerivedB() :a_extension(baseA) {}
double foo(double z) {return a_extension.dosomething();}
};