C++ C++;我是否正确理解多态性?
Bar和Box是Foo的派生类,Foo有一个虚函数F(),Bar和Box都有函数F()。据我所知,多态性正确地允许Bar.F()而不是Box.F()或Box.F()而不是Bar.F()使用一些运行时例程重写Foo.F(),而不知道对象是Bar还是Box。是这样的:C++ C++;我是否正确理解多态性?,c++,polymorphism,derived-class,overriding,C++,Polymorphism,Derived Class,Overriding,Bar和Box是Foo的派生类,Foo有一个虚函数F(),Bar和Box都有函数F()。据我所知,多态性正确地允许Bar.F()而不是Box.F()或Box.F()而不是Bar.F()使用一些运行时例程重写Foo.F(),而不知道对象是Bar还是Box。是这样的: Bar* barry = new Box(); virtual void Func() = 0; // note this --- ^^^^ Foo*boxxy=新框 boxxy->F() 最后一行将调用右侧的F()(在本例中
Bar* barry = new Box();
virtual void Func() = 0;
// note this --- ^^^^
Foo*boxxy=新框
boxxy->F()代码>
最后一行将调用右侧的F()(在本例中为Box.F()),而与boxxy是Box还是Bar或Foo无关(在这种情况下,将调用虚拟Foo.F()的实现)
我理解得对吗?如果boxxy是一个长方体指针,会发生什么变化?如果派生类没有F()的重写,会发生什么?最后,为了避免为基类实现函数,但仍然允许多态性,您是否只编写一个空函数体并将其声明为虚拟?谢谢。
- 我理解得对吗?是,如果函数被声明为虚拟函数
- 如果boxxy是长方体,会发生什么变化
指针?这取决于
函数是否为虚拟函数。虚拟的
函数总是以调用
适当的导出函数;A.
非虚拟函数将调用
版本取决于文件的类型
指针
- 如果派生类
没有F()的重写吗?信息技术
将使用基类定义
- 最后,避免实施
基类的函数,但仍然
允许多态性,你只是写吗
一个空函数体并声明它
事实上的你也可以宣布它是纯的
虚拟:
virtual void F()=0
。任何
要实例化的类
在一个对象中,要覆盖这一点
函数,并给它一个适当的
实施
几乎正确-考虑这个继承树:
Foo
/ \
Bar Box
如果现在创建如下指针:
Bar* barry = new Box();
virtual void Func() = 0;
// note this --- ^^^^
由于框
无法转换为条
:),您将得到一个
所以它只是FooBar
和FooBox
,而不是BarBox
。
接下来,当boxxy
是Box
指针时,它将只调用Box::F
函数(如果提供)。
最后,为了强制子类实现某个函数,您将其声明为纯虚拟的,如下所示:
Bar* barry = new Box();
virtual void Func() = 0;
// note this --- ^^^^
现在,子类(在本例中为Bar
和Box
)必须实现Func
,否则它们将无法编译。是的,将根据通过Foo指针创建的对象类型调用右F()
如果boxxy是一个长方体指针,则只能调用它的F()或它的一个派生类的F(),除非对它的父类执行动态_转换,然后调用F()
为了避免必须在基类中实现,您可以将其定义为纯虚拟,如下所示:
如果boxxy是长方体,会发生什么变化
指针
它将允许访问非从Foo继承的Box方法。长方体指针不能指向条形图对象,因为条形图不是从长方体派生的
如果派生类
没有F()的重写吗
它将从基类继承F()的实现
最后,避免实施
基类的函数,但仍然
允许多态性,你只是写吗
一个空函数体并声明它
虚拟的
它会起作用,但这不是一种正确的方法。如果无法为基类的虚拟函数提供具体的实现,请将该函数设置为纯虚拟函数,不要将其实现为空函数。如果您这样声明Foo
class Foo
{
private:
Foo() {};
public:
void func() const { std::cout << "Calling Foo::func()" << std::endl; }
};
class Bar : public Foo
{
private:
Bar() {};
public:
void func() const { std::cout << "Calling Bar::func()" << std::endl; }
};
class Foo
{
private:
Foo() {};
public:
virtual void func() const { std::cout << "Calling Foo::func()" << std::endl; } // NOTICE THE virtual KEYWORD
};
将调用Foo::func()
如果你像这样声明Foo
class Foo
{
private:
Foo() {};
public:
void func() const { std::cout << "Calling Foo::func()" << std::endl; }
};
class Bar : public Foo
{
private:
Bar() {};
public:
void func() const { std::cout << "Calling Bar::func()" << std::endl; }
};
class Foo
{
private:
Foo() {};
public:
virtual void func() const { std::cout << "Calling Foo::func()" << std::endl; } // NOTICE THE virtual KEYWORD
};
将调用Bar::func()。非常感谢。只是出于好奇,你可以用NULL来代替0,对吗?@Brandon:不,不是在声明纯虚函数时。所需的exakt标记是=0
,除此之外没有其他内容。另外,我鼓励您使用0
而不是NULL
,当C++0x出现时,使用nullptr
作为指针: