美文网首页
关于虚函数

关于虚函数

作者: chjxidian | 来源:发表于2019-12-11 08:40 被阅读0次

(1)派生类对象直接向基类赋值,赋值效果,基类数据成员和派生类中数据成员的值相同;
(2)派生类对象可以初始化基类对象引用;
(3)派生类对象的地址可以赋给基类对象的指针;
(4)函数形参是基类对象或基类对象的引用,在调用函数时,可以用派生类的对象作为实参;
(5)在基类和派生类对象的赋值时,该派生类必须是公有继承的;
(6)只允许派生类对象向基类对象赋值,反过来不允许;
(7)因为虚函数使用的基础是赋值兼容,而赋值兼容成立的条件是派生类之从基类公有派生而来。所以使用虚函数,派生类必须是基类公有派生的;
(8)定义虚函数,不一定要在最高层的类中,而是看在需要动态多态性的几个层次中的最高层类中声明虚函数;
(9)虽然在上述示例代码中main()主函数实现部分,我们也可以使用相应图形对象和点运算符的方式来访问虚函数,如:rectangcle.showArea(),但是这种调用在编译时进行静态联编,它没有充分利用虚函数的特性。只有通过基类对象来访问虚函数才能获得动态联编的特性;
(10)一个虚函数无论配公有继承了多少次,它仍然是虚函数;
(11)虚函数必须是所在类的成员函数,而不能是友元函数,也不能是静态成员函数。因为虚函数调用要靠特定的对象类决定该激活哪一个函数;
(12)内联函数不能是虚函数,因为内联函数是不能在运行中动态确定其位置的即使虚函数在类内部定义,编译时将其看作非内联;
(13)构造函数不能是虚函数,但析构函数可以是虚函数;
(14)如果在main()主函数中用new建立一个派生类无名对象和定义一个基类对象指针,并将无名对象的地址赋给基类对象指针时,当我们用delete运算符来撤销无名对象时,系统只执行基类析构函数,而不执行派生类析构函数;因为在撤销指针graph所指的派生类对象,在调用析构函数时,采用静态联编,只调用了Graph类的析构函数。如果也想调用派生类Rectangle类的析构函数的话,可将Graph类的析构函数定义为虚析构函数。
(15)虽然派生类的析构函数与基类的析构函数名字不同,但是如果将基类的析构函数定义为虚函数,由该基类派生而来的所有派生类的析构函数都自动成为虚函数。我们把上一示例中的Graph类的析构函数前加上关键字virtual;
(16)如果一个类中至少有一个纯虚函数,那么就称该类为抽象类。所以上述中Graph类就是抽象类;
对于抽象类有以下几个注意点:
(1)抽象类只能作为其他类的基类来使用,不能建立抽象类对象;
(2)不允许从具体类中派生出抽象类(不包含纯虚函数的普通类);
(3)抽象类不能用作函数的参数类型、返回类型和显示转化类型;
(4)如果派生类中没有定义纯虚函数的实现,而只是继承成了基类的纯虚函数。那么该派生类仍然为抽象类。
一旦给出了对基类中虚函数的实现,那么派生类就不是抽象类了,而是可以建立对象的具体类;
最后还是一样,我将用一个实例来总结一下今天所讲的内容(开发工具:vs2010):

#include "stdafx.h"
#include <iostream>
#include <string>
class Graph //抽象类
{
protected:
double x;
double y;
public:
Graph(double x,double y);
//void virtual showArea();//定义为虚函数或virtual void showArea()
voidvirtual showArea()=0;//定义纯虚函数
virtual~Graph();//定义虚析构函数
};
Graph::Graph(double x,double y)
{
this->x=x;
this->y=y;
}
void Graph::showArea()
{
    std::cout<<"计算图形面积"<<std::endl;
}
Graph::~Graph()
{
    std::cout<<"调用图形类析构函数"<<std::endl;
}
class Rectangle:public Graph
{
public:
        Rectangle(double x,double y):Graph(x,y){};
void showArea();//虚函数
~Rectangle();//虚析构函数
};
void Rectangle::showArea()
{
    std::cout<<"矩形面积为:"<<x*y<<std::endl;
}
Rectangle::~Rectangle()
{
    std::cout<<"调用矩形类析构函数"<<std::endl;
}
class Triangle:public Graph
{
public:
        Triangle(double d,double h):Graph(d,h){};
virtualvoid showArea();//虚函数
~Triangle();//虚析构函数
};
void Triangle::showArea()
{
    std::cout<<"三角形面积为:"<<x*y*0.5<<std::endl;
}
Triangle::~Triangle()
{
    std::cout<<"调用三角形类析构函数"<<std::endl;
}
class Circle:public Graph
{
public:
        Circle(double r):Graph(r,r){};
virtualvoid showArea();//虚函数
~Circle();//虚析构函数
};
void Circle::showArea()
{
    std::cout<<"圆形面积为:"<<3.14*x*y<<std::endl;
}
Circle::~Circle()
{
    std::cout<<"调用圆形类析构函数"<<std::endl;
}
int main()
{
    {
//Graph g(10,10);//抽象类不能建立对象
        Graph *graph;
        Rectangle rectangle(10,5);
        graph=&rectangle;
        graph->showArea();
        Triangle triangle(5,2.4);
        graph=&triangle;
        graph->showArea();
        Graph *graph1;
        graph1=new Circle(2);//new运算符建立无名对象
        graph1->showArea();
        delete graph1;//delete运算符撤销派生类Circle无名对象
    }
return0;
}

相关文章

网友评论

      本文标题:关于虚函数

      本文链接:https://www.haomeiwen.com/subject/haangctx.html