C ++重写基类本身的Base类的抽象方法?

时间:2012-11-27 20:20:46

标签: c++ class override abstract-class derived-class

如果我有这样的基类:

class Base {
    public:
        Base(){}
        virtual void foo()=0;
};

现在,如果我从Base类中派生出任何类,则必须覆盖foo()

如果我想在基础类的foo()上进行行为怎么办?所以基类有它自己的foo,除此之外,它的每一个都必须覆盖foo?这可能吗?

2 个答案:

答案 0 :(得分:6)

如果您执行以下操作:

class Base {
    public:
        Base(){}
        virtual void foo() = 0;
};
void Base::foo() {
{ 
     cout << "Hello";
}

你将得到一个抽象类,所以你能够创建类Base的对象b并让它通过调用b.foo()来使用你的foo()实现。< / p>

所以这不是你想要的!接下来的问题是,如果您不能使用它,为什么允许您为Base :: foo提供实现。嗯,实际上你可以!不是直接的。

class Deriv : public Base {
    public:
        Deriv(){}
        virtual void foo();
};
void Deriv::foo() 
{ 
     Base::foo(); cout << "  world!";
}

正如您所见,派生类可以使用Base :: foo()

回到你的问题。答案是你可以完全按照你指定的方式完成,除了Base类是抽象的。

替代方法是执行大多数人所做的事情,而不是在Base中为foo()提供实现时指定= 0。这意味着派生类可以覆盖foo()但不具有。这在我看来实际上是完全合理的:在Base :: foo()的默认实现有意义的派生类中,你保留它,但对于那些需要不同的东西,你可以覆盖它。

更新:我试图提出一个实际需要问题的方案,并提出了这个问题:

想象一下,Document及其派生类表示文档类型,Document包含一个虚拟方法getClassIcon(),返回代表文档类型的图标的图像文件的URL。 Document有一个图标(表示通用文档的东西)是有意义的,并且要求所有派生类重写getClassIcon()以提供自己的图标也是有意义的。

话虽如此,在这个特定的例子中,似乎很容易找到另一种设计:使Document :: getClassIcon()成为一个纯虚方法(= 0)(使Document成为一个抽象类)并添加OtherDocument作为其派生之一类,给它以前的getClassIcon文件的实现。 PDFDocument,MSWordDocument等都需要根据需要覆盖getClassIcon()。这个重新设计可能需要揭示的是,之前的设计(由一个假想的C ++版本支持,允许问题所要求的)已经混淆了基类,Document和类的作用。对于不属于任何已知类型的文档,OtherDocument。当然,这一切都在旁观者的眼中:-)有人可能会争辩说第二种设计仅仅是必要的,因为语言缺少功能。我想我们(在很大程度上)根据我们所说的(计算机)语言来思考。 : - )

答案 1 :(得分:3)

您可以为纯虚方法提供实现:

class Base {
  ...
  virtual void foo()=0;
}

void Base::foo() {
     ... implementation goes here ...
}

班级仍然是抽象的。如果您不希望它是抽象的,则必须删除=0。但是,一旦这样做,就无法强制派生类提供自己的实现。

换句话说,你必须做出选择。