3

假设我们有

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。然后我们得到了一个派生自具体类 A 的抽象派生类 B,然后是通过 C 实现的 B。

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

4

4 回答 4

3

重载意味着你有两个同名但参数不同的函数。这不是这里的情况。

例子:

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

重写意味着在子类中重写具有相同参数的函数。这就是你作为例子提出的。

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

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

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

于 2009-01-27T13:05:43.310 回答
1

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

于 2009-01-27T12:48:44.827 回答
1

它仍然是重写的,因为当你有一个指向class 实例的指针p时,仍然调用A*Cp->foo()C::foo()

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

于 2009-01-27T12:51:19.377 回答
1

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

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

于 2009-01-27T15:50:05.383 回答