2

我根据您关于如何最好地在 C++ 中实现继承模式的意见。我有两个基类,比如说

class fooBase{
protected:
    barBase* b;
};

class barBase{};

哪里fooBasebarBase. 我打算把这些类放在一个库中,这样无论我有什么fooBase,它都可以使用它的barBase成员。

我现在打算在特定程序中创建这些专业化

class fooSpec : public fooBase{};
class barSpec : public barBase{};

现在我想fooSpec::b指向 abarSpec而不是 a barBase。我知道我可以只b用 a 进行初始化new barSpec,但这需要我将指针转换为 abarSpec每当我想在专业化中使用特定函数时,不是吗?

有没有另一种方法可以实现这一点?

干杯。

4

6 回答 6

4

Create a method in your specclass to cast the b into the special version. That way instead of casting it all the time, it looks like a getter.

On the other hand OO is about programming towards interfaces and not objects. So what you are doing here looks like programming towards objects. But the is difficult to see as this example is purely theoretical.

于 2013-07-02T14:42:42.493 回答
3

您可以考虑模板解决方案:

template <class T>
class fooBase{
protected:
   T* b;
};

然后将其用作

class fooSpec : public fooBase<barSpec>{};

而通常情况下,基础将用作fooBase<barBase>. 这是你想要的吗?

于 2013-07-02T14:46:06.090 回答
2

Normally we create a function that has the cast and returns the pointer -- and use that instead of the member directly.

于 2013-07-02T14:41:56.883 回答
1

Now I want fooSpec::b to point to a barSpec instead of a barBase.

There's no such thing as fooSpec::b. b belongs to fooBase, and your new class fooSpec is a (specialization of) a fooBase. You can't change the fact that b, a fooBase member, is of type barBase. This is a property of all the instances of fooBase that you can't invalidate in the particular subset of instances concerned by your specialization.

I know that I can just initialise b with a new barSpec, but this would require me to cast the pointer to a barSpec whenever I wanted to use specific functions in the specialisation wouldn't it?

Yes and no. Yes, you need to do that cast; but no, you don't need to do it every time. You can encapsulated in a function of fooSpec.

Is there another way that this is often acheived?

Not that I'm aware of.

于 2013-07-02T14:43:35.673 回答
0

每当我想在专业化中使用特定函数时,这将要求我将指针转换为 barSpec,不是吗?

这取决于您尝试调用的方法是否在超类中定义以及它是否是虚拟的。

如果以下情况之一为真,则需要在调用方法之前强制转换指针...

  1. 该方法只属于子类
  2. 超类有方法的实现,子类的实现不会覆盖超类中的实现。这相当于一个函数是否是虚函数的问题。
于 2013-07-02T15:09:21.070 回答
0

避免在非叶子类中使用数据成员,而是使用纯虚拟 getter。如果你遵循这个简单的规则,你的问题就会自动解决。

这也使得大多数非叶子类自动抽象,这可能看起来像是一个过度的负担,但你习惯了它并最终意识到它是一件好事。

像大多数规则一样,这不是绝对的,需要不时打破,但总的来说,这是一个很好的规则。试试看。

如果它看起来过于极端,您可以尝试其中一种处理双重层次结构的设计模式,例如通往天堂的阶梯。

于 2013-07-02T15:50:33.970 回答