2009-01-27 103 views
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.然后,我们这是从具体类派生的一个抽象的派生类B,然后通过C的实现B的

什么是我们在这里做是否使任何意义?

回答

1

在我看来,纯虚拟方法的唯一影响是让B成为抽象类。

1

它仍然是压倒一切的,因为当你有A*类型的指针pC类的实例,p->foo()还叫C::foo()

也许,设计师要插入层次结构中的一个抽象类,从一些具体的类派生,并强制在子类中重写该方法。我不认为这是非常明智的。

3

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

实施例:

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

重写装置重写与在子类中的相同参数的函数。这就是你作为一个例子提出的。

这就是定义的一部分。现在进行设计:

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

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

+0

是的,它看起来“可疑”,但我不会说它本身就是一个缺陷,也许在现实世界的代码中它是有意义的。顺便说一句,+1,因为你是唯一一个回答超载/压倒性部分:) – 2009-01-27 13:12:37

1

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

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