我对如何最好地在C ++中实现继承模式表示意见。我有两个基类,比如说
class fooBase{
protected:
barBase* b;
};
class barBase{};
其中fooBase
有barBase
。我打算将这些类放在库中,这样只要我有fooBase
,它就可以使用它的barBase
成员。
我现在打算在特定程序中创建这些的专门化
class fooSpec : public fooBase{};
class barSpec : public barBase{};
现在我希望fooSpec::b
指向barSpec
而不是barBase
。我知道我可以用b
初始化new barSpec
,但这需要我将指针强制转换为barSpec
,只要我想在专门化中使用特定的函数就不行了?
还有其他方法可以实现吗?
干杯。
答案 0 :(得分:4)
在您的specclass中创建一个方法,将b转换为特殊版本。 这样,它不是一直投射,而是看起来像一个吸气剂。
另一方面,OO是关于接口而不是对象的编程。所以你在这里做的就像编写对象一样。但很难看出这个例子纯粹是理论上的。
答案 1 :(得分:3)
您可以考虑模板解决方案:
template <class T>
class fooBase{
protected:
T* b;
};
然后将其用作
class fooSpec : public fooBase<barSpec>{};
虽然通常,基数将用作fooBase<barBase>
。
这是你想要的吗?
答案 2 :(得分:2)
通常我们创建一个具有强制转换并返回指针的函数 - 并直接使用它而不是成员。
答案 3 :(得分:1)
现在我希望fooSpec :: b指向barSpec而不是barBase。
没有fooSpec::b
之类的东西。 b
属于fooBase
,您的新班级fooSpec
是fooBase
的(特化)。您无法更改b
fooBase
成员属于barBase
类型的事实。这是fooBase
的所有实例的属性,您无法在您的专业化所涉及的特定实例子集中失效。
我知道我可以用新的barSpec初始化b,但是这样会 要求我在每次使用时将指针强制转换为barSpec 专业化中的具体功能不是吗?
是和否。是的,你需要做那个演员;但不,你不需要每次都这样做。您可以使用fooSpec
。
还有其他方法可以实现吗?
不是我知道的。
答案 4 :(得分:0)
这会要求我在指向专门化时使用特定函数时将指针强制转换为barSpec吗?
这取决于您尝试调用的方法是否在超类中定义,以及它是否为虚拟。
如果满足下列条件之一,则需要在调用方法之前强制转换指针...
答案 5 :(得分:0)
避免非叶类中的数据成员,而是使用纯虚拟getter。如果您遵循这个简单的规则,您的问题将自动解决。
这也使得大多数非叶类自动抽象化,起初看起来似乎是一种不适当的负担,但你已经习惯了它并最终意识到它是一件好事。
与大多数规则一样,这个规则并不是绝对的,需要时不时地打破,但总的来说这是一个很好的规则。试一试。
如果它看起来太极端,你可以尝试一种处理双重层次结构的设计模式,例如Stairway to Heaven。