C++在基类本身中重写基类的抽象方法
C++ overriding abstract method of Base class in the base class itself?
如果我有一个基类,那么:
class Base {
public:
Base(){}
virtual void foo()=0;
};
现在,如果我从基类派生任何类,它将不得不重写foo()
。
如果我也想要基类在foo()
上的行为呢?所以这个基类有自己的foo
,除此之外,它的每一个都必须重写foo
?这可能吗?
如果您执行以下操作:
class Base {
public:
Base(){}
virtual void foo() = 0;
};
void Base::foo() {
{
cout << "Hello";
}
您将获得一个抽象类,因此您将不能创建基类的对象b,并通过调用b.foo()使其使用您的foo(()实现。
所以这不是你想要的!下一个问题是,如果你不能使用Base::foo,为什么允许你提供它的实现。好吧,实际上你可以!但不是直接的。
class Deriv : public Base {
public:
Deriv(){}
virtual void foo();
};
void Deriv::foo()
{
Base::foo(); cout << " world!";
}
正如您所看到的,Base::foo()可以被派生类使用。
回到你的问题上来。答案是可以完全按照您指定的操作,除了基类是抽象的。
另一种选择是按照大多数人的做法,当您在Base中为foo()提供实现时,不要指定=0。这意味着派生类可以覆盖foo(),但没有覆盖。在我看来,这实际上是完全合理的:在Base::foo()的默认实现有意义的派生类中,你可以保留它,但对于那些需要不同东西的类,你可以覆盖它。
更新:我试图提出一个实际需要问题的场景,并提出了这个:
假设Document及其派生类表示文档类型,并且Document包含一个虚拟方法getClassIcon(),该方法返回表示文档类型的图标的图像文件的URL。Document有一个图标(表示通用文档的东西)是有意义的,要求所有派生类重写getClassIcon()以提供自己的图标也是有意义的。
话虽如此,在这个特定的例子中,似乎很容易找到另一种设计:使Document::getClassIcon()成为一个纯虚拟方法(=0)(使Document成为一个抽象类),并将OtherDocument添加为其派生类之一,从而实现之前的getClassIconDocument。PDFDocument、MSWordDocument等都需要根据需要重写getClassIcon()。这种重新设计可能会揭示的是,以前的设计(由C++的想象版本支持,该版本允许问题的要求)将基类Document的角色和代表不属于任何已知类型的文档的类OtherDocument的角色混为一谈。当然,这一切都在旁观者的眼中:-)有人可能会说,第二个设计只是因为语言中缺少功能而变得必要。我想我们(在很大程度上)是根据我们所说的(计算机)语言来思考的
您可以为纯虚拟方法提供一个实现:
class Base {
...
virtual void foo()=0;
}
void Base::foo() {
... implementation goes here ...
}
这个类仍然是抽象的。如果你不想让它抽象,你必须删除=0
。但是,一旦这样做,就不能强制派生类提供它们自己的实现。
换句话说,你必须做出选择。
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 重写打印函数而不是覆盖基类
- 重写函数不打印基类数据
- 从基类调用重写的方法
- 我无法重写基类的方法,因为我的派生类是模板化的
- 哪个基类调用派生重写的方法?
- 如何在子类中重写时调用私有虚拟基类实现
- 在 c++ 中重写函数时如何选择基类?
- 基类能否知道派生类是否已重写虚拟方法
- 给定基类方法的编译时重写
- C ++中有没有办法让派生类重写基类静态方法
- 在派生类中重写哪个基类的虚拟析构函数
- 重写基类中的编译器宏
- 继承和重写 - 从基类调用重写子方法
- C++ - 如何使用基指针重写子类方法
- 重写模板基类中的纯虚拟函数
- 在继承时用指向派生类的指针重写指向基类的指针
- 调用重写函数并使用基类中的重载变量
- C++:从模板化基类重写函数
- 从基类重写虚方法