用纯虚方法重写(常规)虚方法有什么效果?

发布于 2024-07-12 06:05:22 字数 431 浏览 7 评论 0原文

假设我们有

class A {    
public:    
    virtual int foo() { cout << "foo!"; }    
}

class B : public A {
public:    
    virtual int foo() =0;
}

class C : public B {
public:
    virtual int foo() { cout << "moo!"; }
}

这真的压倒一切吗? 我认为这实际上是超载。 从设计角度来说,制作这样的东西有何意义?

我们得到了一个基类 A。然后我们得到了一个抽象派生类 B,它派生自具体类 A,然后通过 C 实现了 B。

我们在这里做什么,它有什么意义吗?

Let's say we have

class A {    
public:    
    virtual int foo() { cout << "foo!"; }    
}

class B : public A {
public:    
    virtual int foo() =0;
}

class C : public B {
public:
    virtual int foo() { cout << "moo!"; }
}

Is this really overriding? I think this is actually overloading.
What is the meaning of making something like this, design-wise?

We got a base class A. Then we got an abstract derived class B which is derived from the concrete class A, and then a realization of B via C.

What are we doing here and does it make any sense?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

吃→可爱长大的 2024-07-19 06:05:22

重载意味着您​​有两个同名但参数不同的函数。 这里的情况并非如此。

示例:

int functionA() { /*...*/ };
int functionA(int someParameter) { /*...*/ };

重写是指在子类中重写具有相同参数的函数。 这就是您所举的例子。

这就是定义部分。 现在开始设计:

当你有一个纯虚函数时,具体的子类必须重写它。 因此,通过添加纯虚函数,您可以确保所有子类提供相同的函数集(=接口)。 示例代码中似乎就是这种情况。

但这不是一个很好的例子,因为具体的超类已经实现了 foo() 的默认功能。 当有一个抽象子类将其重新定义为纯虚拟时,对我来说,这表明类层次结构有缺陷,因为子类(以及 foo() 的调用者)通常应该能够回退到默认实现。 用这样一个抽象的例子来解释有点困难,但这样的层次结构在我看来有点可疑。

Overloading would mean that you had two functions of the same name but with different parameters. That's not the case here.

Example:

int functionA() { /*...*/ };
int functionA(int someParameter) { /*...*/ };

Overriding means rewriting a function with the same parameters in a subclass. That is what you presented as an example.

That's the definition part. Now on to the design:

When you have a pure virtual function, concrete subclasses have to override it. So by adding a pure virtual function, you ensure that all subclasses provide the same set of functions (=interface). This seems to be the case in the sample code.

But it is not a very good example, as the concrete superclass already implements a default functionality for foo(). When there is an abstract subclass that redefines it to be purely virtual, it is a sign for me that the class hierarchy is flawed because a subclass (and the callers of foo()) usually should be able to fall back to the default implementation. It's a bit hard to explain with such an abstract example, but a hierarchy like this is a bit suspicious to my eye.

感性不性感 2024-07-19 06:05:22

在我看来,这里纯虚方法的唯一作用就是使B成为一个抽象类。

It seems to me that the only effect of the pure virtual method here is to make B an abstract class.

甜警司 2024-07-19 06:05:22

它仍然是压倒性的,因为当你有一个 A* 类型的指针 p 指向类 C 的实例时,p->foo () 仍然调用 C::foo()

可能,设计者想要在派生自某个具体类的层次结构中插入一个抽象类,并强制重写子类中的方法。 我不认为这是非常明智的。

It's still overriding, because when you have a pointer p of type A* to instance of class C, p->foo() still calls C::foo()

Probably, the designer wanted to insert an abstract class in the hierarchy deriving from some concrete class, and force overriding of the method in subclasses. I don't think it's terribly wise.

向地狱狂奔 2024-07-19 06:05:22

您是说从 B 派生的类必须实现 int foo(); 。 您可能想做这样的事情来迫使其他程序员考虑他们希望 foo() 如何表现,但我认为这是一个坏主意 - 实际上他们很可能通过调用 < em>A::foo()。

如果您只想使 B 抽象,请给它一个纯虚拟析构函数 - 您还需要提供析构函数的实现以避免链接错误。

You're saying that classes deriving from B must implement int foo();. You might want to do something like this to force other programmers to think about how they want foo() to behave, but I think it's a bad idea - in reality they're likely to implement by calling A::foo().

If you just want to make B abstract, give it a pure virtual destructor - you'll also need to provide an implementation of the destructor to avoid link error though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文