har*_*ris 43 c++ virtual-functions
可能重复:
有人可以解释C++虚拟方法吗?
我有一个关于C++虚函数的问题.
我们为什么以及何时使用虚拟功能?任何人都可以给我一个实时实现或使用虚拟功能?
Alo*_*ave 56
如果要覆盖派生类的某个行为(读取方法)而不是为基类实现的行为(并且希望在运行时通过指向基类的指针)执行此操作,则可以使用虚函数.
经典的例子是当你有一个被调用的基类Shape和从中派生出来的具体形状(类).每个具体类都会覆盖(实现一个虚方法)Draw().
类层次结构如下:

以下代码段显示了示例的用法; 它创建了一个Shape类指针数组,其中每个指针都指向一个不同的派生类对象.在运行时,调用该Draw()方法会导致调用该派生类重写的方法,并Shape绘制(或呈现)特定的方法.
Shape *basep[] = { &line_obj, &tri_obj,
&rect_obj, &cir_obj};
for (i = 0; i < NO_PICTURES; i++)
basep[i] -> Draw ();
Run Code Online (Sandbox Code Playgroud)
上面的程序只使用指向基类的指针来存储派生类对象的地址.这提供了松散耦合,因为如果shape随时添加新的具体派生类,则程序不必急剧改变.原因是实际使用(依赖)具体Shape类型的代码段很少.
以上是着名的SOLID设计原则的开放闭合原理的一个很好的例子.
Vol*_*dyi 24
当您需要以相同方式处理不同对象时,可以使用虚函数.它被称为多态性.让我们假设您有一些基类 - 类似于经典形状:
class Shape
{
public:
virtual void draw() = 0;
virtual ~Shape() {}
};
class Rectange: public Shape
{
public:
void draw() { // draw rectangle here }
};
class Circle: public Shape
{
public:
void draw() { // draw circle here }
};
Run Code Online (Sandbox Code Playgroud)
现在你可以拥有不同形状的矢量:
vector<Shape*> shapes;
shapes.push_back(new Rectangle());
shapes.push_back(new Circle());
Run Code Online (Sandbox Code Playgroud)
你可以画出这样的形状:
for(vector<Shape*>::iterator i = shapes.begin(); i != shapes.end(); i++)
{
(*i)->draw();
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以使用一个虚拟方法绘制不同的形状 - draw().根据有关指针后面对象类型的运行时信息选择正确版本的方法.
注意 当您使用虚函数时,您可以将它们声明为纯虚函数(如在类Shape中,只需在方法proto之后放置"= 0").在这种情况下,您将无法使用纯虚函数创建对象实例,它将被称为Abstract类.
在析构函数之前还要注意"虚拟".如果您计划通过指向其基类的指针来处理对象,则应该声明析构函数为virtual,因此当您为基类指针调用"delete"时,将调用所有析构函数链并且不会发生内存泄漏.
hol*_*gac 21
想想动物类,从它衍生出来的是猫,狗和牛.动物类有一个
virtual void SaySomething()
{
cout << "Something";
}
Run Code Online (Sandbox Code Playgroud)
功能.
Animal *a;
a = new Dog();
a->SaySomething();
Run Code Online (Sandbox Code Playgroud)
狗不应该打印"Something",而应该说"Bark",猫应该说"Meow".在这个例子中,你看到a是一只狗,但有时候你有一个动物指针并且不知道它是哪种动物.你不想知道它是哪种动物,你只想让动物说些什么.所以你只需要调用虚函数,猫会说"喵",狗就会说"吠".
当然,SaySomething函数应该是纯虚拟的,以避免可能的错误.