我在C ++中有一个工作设计,如下所示:
struct E {
int some_properties ;
// … some more
};
class A {
public:
void tick() {
std::swap(futur, past) ;
}
void do_something() {
// do something (read past, write futur)
futur->some_properties = past->some_properties + 1 ;
}
E* past ;
protected:
E* futur ;
};
现在,我想创建一个class B
,使用新的class A
方法继承void do_other_thing()
,并使用struct F
继承struct E
新的int some_other ;
属性。
方法void do_other_thing()
可以是例如:
void do_other_thing() {
// do something (read past, write futur)
futur->some_properties = past->some_properties + past->some_other ;
futur->some_other = past->some_other + 1 ;
}
我对如何实现这种继承感到非常困惑。
特别是在实现这种用例时:
// A a ;
a.tick() ;
a.do_something() ;
并且:
// B b ;
b.tick()
b.do_something() ;
b.tick() ;
b.do_other_thing() ;
问题出现了:
这是否可能?
如果是,怎么做?
如果没有,如何以更好的结构解决问题?
编辑:
如上所述,最简单的继承模式将是:
class B : public A {
void do_other_thing(){ // Something }
}
struct F : public E {
int some_other;
}
遇到的问题是past
和futur
这里是E
指针:
void do_other_thing() {
// do something (read past, write futur)
futur->some_properties = past->some_properties + past->some_other ;
futur->some_other = past->some_other + 1 ;
}
答案 0 :(得分:1)
你可以dynamic_cast
:
void do_other_thing() {
F* futur_f = dynamic_cast<F*>(futur);
F* past_f = dynamic_cast<F*>(past);
assert(futur_f && past_f);
futur_f->some_properties = past_f->some_properties + past_f->some_other ;
futur_f->some_other = past_f->some_other + 1 ;
}
或者你可以使用B
中的第二对指针成员指向与futur
和past
相同的对象(更多数据,更少的转换 - 基本上缓存运行时强制转换)
或者您可以使用模板基类,其中past
和futur
的类型是模板参数(有时需要引入非模板化的“根类”并使所有内容都是虚拟的)。
可能还有其他一些方法,有不同的权衡,好处和复杂性。
选择什么取决于您的计划的其余部分和您的个人喜好。
答案 1 :(得分:0)
首先,是的,这是可能的。以下只是用于说明的伪代码:
class B : public A {
void do_other_thing(){ std::cout << "Other" << std::endl; }
}
struct F : public E {
int some_other;
}
现在这两种新类型都将遵循能够取代其父类型的原则。这是通过指向其基类型(多态)的指针来实现的。
std::shared_ptr<A> baseARefToB{ std::make_shared<B>() };
baseRefToB->do_something();
std::shared_ptr<E> baseERefToF{ std::make_shared<F>() };
baseERefToF->some_properties = 3;
请注意,我无法通过基类引用访问其子类方法和属性。但是:
std::static_pointer_cast<B>(baseRefToB)->do_other_thing();
std::static_pointer_cast<E>(baseERefToF)->some_other = 42;
这里我将对它们的基类型的引用强制转换,以便我可以访问它们的子类特定功能。
因此,从您的问题描述中,您将能够(始终)为所有类型的do_something
和some_properties
调用基类功能(A
和E
),但如果通过具有正确类型的指针引用对象,则只能访问子类功能。