C++我对多态性的理解正确吗?
Bar 和 Box 是 Foo 的派生类,Foo 有一个虚函数 F(),而 Bar 和 Box 都有函数 F()。据我了解,多态性正确地允许 Bar.F() 而不是 Box.F() 或 Box.F() 而不是 Bar.F() 使用某些运行时例程覆盖 Foo.F(),而不知道您的对象是否是一个酒吧或一个盒子。它是这样的:
Foo * boxxy = new Box;
boxxy->F();
最后一行将调用右侧的 F()(在本例中为 Box.F()),无论 boxxy 是 Box、Bar 还是 Foo(在本例中)调用虚拟 Foo.F() 的实现)。
我这样理解对吗?如果 boxxy 是 Box 指针,会发生什么变化?如果派生类没有覆盖 F() 会发生什么?最后,为了避免为基类实现函数但仍然允许多态性,您是否只编写一个空函数体并将其声明为虚拟?谢谢。
Bar and Box are derived classes of Foo and Foo has a virtual function F() and Bar and Box both have function F(). From what I understand, polymorphism correctly allows Bar.F() instead of Box.F() or Box.F() instead of Bar.F() to override Foo.F() using some runtime routine without knowing whether your object is a Bar or a Box. It's something like this:
Foo * boxxy = new Box;
boxxy->F();
The last line will call the right F() (in this case, Box.F()) independent of whether boxxy is a Box or a Bar or a Foo (in which case the implementation of the virtual Foo.F() is called).
Do I understand this right? And what changes if boxxy is a Box pointer? And what happens if the derived class doesn't have an override for F()? Lastly, to avoid implementing a function for a base class but still allow polymorphism, do you just write an empty function body and declare it virtual? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
几乎正确 - 考虑这个继承树:
如果您现在创建这样的指针:
您将得到一个 nice 编译器错误 ,因为
Box
无法转换为Bar
。 :)所以它只是
Foo<->Bar
和Foo<->Box
,而不是Bar<->Box
。接下来,当
boxxy
是Box
指针时,它只会调用Box::F
函数(如果提供)。最后,要强制子类实现某个功能,您可以将其声明为
pure virtual
,如下所示:现在是子类(在本例中为
Bar
和Box
>),必须实现Func
,否则编译失败。Nearly right - consider this inheritance tree:
If you now make a pointer like this:
You'll get a nice compiler error, since a
Box
can't be converted to aBar
. :)So it's only
Foo<->Bar
andFoo<->Box
, neverBar<->Box
.Next, when
boxxy
is aBox
pointer, it will only ever call theBox::F
function, if it is provided.And last, to force subclasses to implement a certain function, you declare it
pure virtual
, like this:Now subclasses (in this case
Bar
andBox
), must implementFunc
, else they will fail to compile.是的,将根据您通过 Foo 指针创建的对象类型来调用正确的 F() 。
如果 boxxy 是一个 Box 指针,您只能调用它的 F() 或其派生类之一的 F(),除非您对其父类进行了动态转换,然后调用 F()。
为了避免在基类中实现,您可以将其定义为纯虚拟,如下所示:
Yes the right F() will be called dependent on the type of object you have created through your Foo pointer.
If boxxy were a Box pointer you could only call it's F() or one of it's derived class's F(), unless you did a dynamic_cast to it's parent class and then called F().
To avoid having to implement in the base class you define it as pure virtual like so:
它将允许访问不是从 Foo 继承的 Box 的方法。 Box 指针不能指向 Bar 对象,因为 Bar 不是从 Box 派生的。
它将从基类继承 F() 的实现。
它会起作用,但它不是进行多态性的正确方法。如果您无法为基类的虚函数提供具体的实现,请将该函数设为纯虚函数,不要将其实现为空函数。
It will allow access to the methods of Box not inherited from Foo. Box pointer can't point to Bar objects, since Bar isn't derived from Box.
It will inherit the implementation of F() from the base class.
It will work, but it is not a right way to do polymorphism. If you can't come up with a concrete implementation for the virtual function of the base class make that function pure virtual, don't implement it as empty function.
如果你像这样声明 Foo
并像这样声明 Bar
那么
将调用 Foo::func()。
如果你像这样声明 Foo
那么
将会调用 Bar::func()。
If you declare Foo like this
and Bar like this
then
will call Foo::func().
If you declare Foo like this
then
will call Bar::func().
指针?取决于是否
函数是否为虚函数。一个虚拟的
函数总是会调用
正确的导出函数;一个
非虚函数将调用
版本基于类型
指针。
没有 F() 的覆盖吗?它
将使用基类定义。
基类的函数,但仍然
允许多态,你就这样写
一个空函数体并声明它
虚拟的?你也可以声明它是纯的
虚拟:
虚拟 void F() = 0
。任何打算实例化的类
进入一个对象,很大程度上覆盖了 this
函数并给它一个适当的
执行。
pointer? Depends on whether the
function is virtual or not. A virtual
function will always end up calling
the proper derived function; a
non-virtual function will call the
version based on the type of the
pointer.
doesn't have an override for F()? It
will use the base class definition.
function for a base class but still
allow polymorphism, do you just write
an empty function body and declare it
virtual? You can also declare it pure
virtual:
virtual void F() = 0
. Anyclass that intends to be instantiated
into an object much override this
function and give it a proper
implementation.