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()的覆盖会发生什么?最后,为了避免为基类实现一个函数但仍然允许多态,你是否只编写一个空函数体并将其声明为虚拟?感谢。
答案 0 :(得分:2)
几乎正确 - 考虑这个继承树:
Foo
/ \
Bar Box
如果你现在制作一个这样的指针:
Bar* barry = new Box();
您将获得nice compiler error,因为Box
无法转换为Bar
。 :)
所以它只有Foo<->Bar
和Foo<->Box
,而不是Bar<->Box
。
接下来,当boxxy
是Box
指针时,它只会调用Box::F
函数(如果已提供)。
最后,为了强制子类实现某个函数,你将它声明为pure virtual
,如下所示:
virtual void Func() = 0;
// note this --- ^^^^
现在子类(在这种情况下为Bar
和Box
),必须实现Func
,否则它们将无法编译。
答案 1 :(得分:1)
是的,将根据您通过Foo指针创建的对象类型调用正确的F()。
如果boxxy是一个Box指针,你只能调用它的F()或它的一个派生类的F(),除非你对它的父类做了一个dynamic_cast然后调用F()。
为避免必须在基类中实现,您将其定义为纯虚拟,如下所示:
class Foo
{
public:
virtual void F() = 0; //notice the = 0, makes this function pure virtual.
};
答案 2 :(得分:1)
如果boxxy是Box,会发生什么变化 指针?
它将允许访问未从Foo继承的Box方法。 Box指针不能指向Bar对象,因为Bar不是从Box派生的。
如果派生类会发生什么 没有F()的覆盖?
它将从基类继承F()的实现。
最后,要避免实施 基类的功能,但仍然 允许多态,你刚才写 一个空的函数体并声明它 虚拟?
它会起作用,但它不是一种做多态的正确方法。如果你不能为基类的虚函数提出具体的实现,那就使该函数成为纯虚函数,不要将它实现为空函数。
答案 3 :(得分:1)
如果你像这样声明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()。
答案 4 :(得分:0)
virtual void F() = 0
。任何
打算实例化的类
进入一个对象很多覆盖它
功能并给它一个适当的
实施