C++ 为什么我要实现虚拟函数而不在抽象类中实现?
对不起,我得问一个愚蠢的问题。 我理解实现抽象类的好处。如果我有一个基本实现的虚拟函数,它总是在派生类没有特定实现的情况下被调用,那么肯定会有好处,例如。C++ 为什么我要实现虚拟函数而不在抽象类中实现?,c++,abstract-class,virtual,C++,Abstract Class,Virtual,对不起,我得问一个愚蠢的问题。 我理解实现抽象类的好处。如果我有一个基本实现的虚拟函数,它总是在派生类没有特定实现的情况下被调用,那么肯定会有好处,例如。 virtualvoid ImplementedVirtFunc(){//do something basic} 我不太明白的是,实现一个纯粹的虚拟函数,比如 virtualvoid VirtFunc()=0 在这种情况下,如果需要,我的派生类无论如何都需要实现专门化的函数。但是我可以直接在那里实现它,并在我的抽象类中省略虚拟void Virt
virtualvoid ImplementedVirtFunc(){//do something basic}
我不太明白的是,实现一个纯粹的虚拟函数,比如
virtualvoid VirtFunc()=0代码>
在这种情况下,如果需要,我的派生类无论如何都需要实现专门化的函数。但是我可以直接在那里实现它,并在我的抽象类中省略虚拟void VirtFunc()=0
行
那么实现virtualvoid VirtFunc()=0
是否有我看不到的特殊好处呢
请原谅我这个愚蠢的问题。今年一月我开始学习C++,我还有很长的路要走,去理解所有的细微之处……
virtual void f(); // virtual member function
virtual void g() = 0; // pure abstract member function
至少有一个纯虚成员函数的类是一个抽象类,不能自行构造,这通常是需要的(只有非抽象的“具体的”,如果您愿意的话,应该能够构造派生类)
抽象类通常以多态方式使用,以允许动态分派到派生对象方法:
struct Derived : public Abstract {
void g() override {} // #1
}
void h(Abstract const& obj) {
obj.g(); // dynamic dispatch
}
int main() {
Derived d{};
h(d); // Will result in invoke #1
}
但我可以直接在那里实现它,并在抽象类中省略虚拟void VirtFunc()=0行
当然可以。但是您不能从基类调用该方法,因为您的基类根本不知道它的存在
考虑下面的例子。每个形状
肯定都有一个区域,即使一般形状不知道。Shape
的每个子类都继承了Print()
方法
类形状{
// ...
公众:
virtual int Area()=0;//对于“一般”形状的面积没有公式,但它肯定有一个公式。。。
虚拟空打印(){
有两个原因。
一种是强制派生的具体类实现虚拟函数。
第二种方法是使您的类成为一个抽象类,而抽象类本身无法实例化。当基类没有函数的实现,并且您希望强制派生类提供函数时,会使用virtual void VirtFunc()=0
。“但我可以直接在那里实现它。”-如何实现?假设在父类中始终有一种实现“基本版本”的方法,您可以找到大量不可能实现的示例(或者技术上可行但没有意义)。有时,在基类中没有合理的默认行为可以实现。@Jarod42,我认为这取决于实际的用例。抽象类提供了一个框架,因此可能有一些有用的默认实现,也可能没有。一个“有趣的”事情是,您可以将虚拟函数声明为“纯”-因此需要重写-并在同一个类中为其提供定义。不过,我不记得我是否见过它的良好用途。仅当派生类本身希望成为非抽象类(通常情况下)时,派生类本身不会被迫实现虚函数。多接口继承并不少见(例如),而多实现继承通常是(首选…)不赞成,而不是简单地使用组合。@dfrib:你能解释一下多重接口继承和多重实现继承的含义吗?@许多问题都说a
是抽象的,假设B:a
,C:B
。如果你从未实例化B
,B
你不必重写A
的虚拟函数。但是,如果你实例化C
,你必须重写A
的虚拟函数。这是一个完美的例子。干得好。我本来打算用Draw()
做同样的回答。回答得好
struct Derived : public Abstract {
void g() override {} // #1
}
void h(Abstract const& obj) {
obj.g(); // dynamic dispatch
}
int main() {
Derived d{};
h(d); // Will result in invoke #1
}