C++我对多态性的理解正确吗?

发布于 2024-11-01 03:59:46 字数 429 浏览 1 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

不顾 2024-11-08 03:59:46

几乎正确 - 考虑这个继承树:

      Foo
     /   \
   Bar   Box

如果您现在创建这样的指针:

Bar* barry = new Box();

您将得到一个 nice 编译器错误 ,因为 Box 无法转换为 Bar。 :)
所以它只是 Foo<->BarFoo<->Box,而不是 Bar<->Box
接下来,当 boxxyBox 指针时,它只会调用 Box::F 函数(如果提供)。
最后,要强制子类实现某个功能,您可以将其声明为pure virtual,如下所示:

virtual void Func() = 0;
//   note this --- ^^^^

现在是子类(在本例中为BarBox >),必须实现Func,否则编译失败。

Nearly right - consider this inheritance tree:

      Foo
     /   \
   Bar   Box

If you now make a pointer like this:

Bar* barry = new Box();

You'll get a nice compiler error, since a Box can't be converted to a Bar. :)
So it's only Foo<->Bar and Foo<->Box, never Bar<->Box.
Next, when boxxy is a Box pointer, it will only ever call the Box::F function, if it is provided.
And last, to force subclasses to implement a certain function, you declare it pure virtual, like this:

virtual void Func() = 0;
//   note this --- ^^^^

Now subclasses (in this case Bar and Box), must implement Func, else they will fail to compile.

过期情话 2024-11-08 03:59:46

是的,将根据您通过 Foo 指针创建的对象类型来调用正确的 F() 。

如果 boxxy 是一个 Box 指针,您只能调用它的 F() 或其派生类之一的 F(),除非您对其父类进行了动态转换,然后调用 F()。

为了避免在基类中实现,您可以将其定义为纯虚拟,如下所示:

class Foo
{
public:
    virtual void F() = 0; //notice the = 0, makes this function pure virtual.

};

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:

class Foo
{
public:
    virtual void F() = 0; //notice the = 0, makes this function pure virtual.

};
夜司空 2024-11-08 03:59:46

如果 boxxy 是一个 Box,会发生什么变化
指针?

它将允许访问不是从 Foo 继承的 Box 的方法。 Box 指针不能指向 Bar 对象,因为 Bar 不是从 Box 派生的。

如果派生类会发生什么
没有 F() 的覆盖吗?

它将从基类继承 F() 的实现。

最后,为了避免实施
基类的函数,但仍然
允许多态,你就这样写
一个空函数体并声明它
虚拟?

它会起作用,但它不是进行多态性的正确方法。如果您无法为基类的虚函数提供具体的实现,请将该函数设为纯虚函数,不要将其实现为空函数。

And what changes if boxxy is a Box
pointer?

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.

And what happens if the derived class
doesn't have an override for F()?

It will inherit the implementation of F() from the base class.

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?

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.

雅心素梦 2024-11-08 03:59:46

如果你像这样声明 Foo

class Foo
{
private:
  Foo() {};
public:
  void func() const { std::cout << "Calling Foo::func()" << std::endl; }
};

并像这样声明 Bar

class Bar : public Foo
{
private:
  Bar() {};
public:
  void func() const { std::cout << "Calling Bar::func()" << std::endl; }
};

那么

Foo* bar = new Bar();
bar->func();

将调用 Foo::func()。

如果你像这样声明 Foo

class Foo
{
private:
  Foo() {};
public:
  virtual void func() const { std::cout << "Calling Foo::func()" << std::endl; } // NOTICE THE virtual KEYWORD
};

那么

Foo* bar = new Bar();
bar->func();

将会调用 Bar::func()。

If you declare Foo like this

class Foo
{
private:
  Foo() {};
public:
  void func() const { std::cout << "Calling Foo::func()" << std::endl; }
};

and Bar like this

class Bar : public Foo
{
private:
  Bar() {};
public:
  void func() const { std::cout << "Calling Bar::func()" << std::endl; }
};

then

Foo* bar = new Bar();
bar->func();

will call Foo::func().

If you declare Foo like this

class Foo
{
private:
  Foo() {};
public:
  virtual void func() const { std::cout << "Calling Foo::func()" << std::endl; } // NOTICE THE virtual KEYWORD
};

then

Foo* bar = new Bar();
bar->func();

will call Bar::func().

森林散布 2024-11-08 03:59:46
  • 我这样理解对吗?是的,如果该函数被声明为虚函数。
  • 如果 boxxy 是一个 Box,会发生什么变化
    指针?取决于是否
    函数是否为虚函数。一个虚拟的
    函数总是会调用
    正确的导出函数;一个
    非虚函数将调用
    版本基于类型
    指针。
  • 如果派生类会发生什么
    没有 F() 的覆盖吗?它
    将使用基类定义。
  • 最后,为了避免实施
    基类的函数,但仍然
    允许多态,你就这样写
    一个空函数体并声明它
    虚拟的?你也可以声明它是纯的
    虚拟:虚拟 void F() = 0。任何
    打算实例化的类
    进入一个对象,很大程度上覆盖了 this
    函数并给它一个适当的
    执行。
  • Do I understand this right? Yes, if the function was declared as a virtual function.
  • And what changes if boxxy is a Box
    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.
  • And what happens if the derived class
    doesn't have an override for F()? It
    will use the base class definition.
  • 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? You can also declare it pure
    virtual: virtual void F() = 0. Any
    class that intends to be instantiated
    into an object much override this
    function and give it a proper
    implementation.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文