重拾C++之虚函数和虚基类以及抽象类

1、引言

    很久没接触过C++了,今天忽然要用一点感受号蛋疼,用惯了python感受C++一点都不会了。java

声明了一个类的对象竟然用这种方法,脑子绝对是被驴(python)踢了
class A{
 ...
 }
 a=A();//尼玛这都能行,被踢大了
2、虚函数和通常函数

    虚函数就是加了vritual关键字的函数,引入虚函数的目的是为了实现多态性(在此为运行时的多态性),便可以经过父类的指针调用子类的对象,从而产生不一样的效果。
python

    virtual void show(){
        cout<<"hello my name is a"<<endl;
    }

    废话很少说,为了展现虚函数和通常函数的区别看看下面一个个例子:ios

#include<iostream>
using namespace std;

class A{
private:
    int a;
    int b;
public:
    A(int a,int b){
        this->a=a;
	this->b=b;
        cout<<"hello base A"<<endl;
        cout<<a<<'-'<<b<<endl;
    }
    //定义一个虚函数
    virtual void show(){
        cout<<"hello my name is a"<<endl;
    }
};
class D:public A{
public:
    D(int a,int b):A(a,b){
        cout<<"hello base A"<<endl;
        cout<<a<<'-'<<b<<endl;
    }
    void show(){
        cout<<"hello my name is d"<<endl;
    }
};
class E:public A{
public:
    E(int a,int b):A(a,b){
        cout<<"hello base A"<<endl;
        cout<<a<<'-'<<b<<endl;
    }
    void show(){
        cout<<"hello my name is e"<<endl;
    }
};
int main()
{
    A *p;
    D d = D(1,2);
    p=&d;
    p->show();
    E e = E(1,2);
    p=&e;
    p->show();
}

    编译,运行输出中有这么两行:函数

hello my name is d
hello my name is e

    而后去掉关键字vritual,在编译运行,上面两行变成了this

hello my name is a
hello my name is a

    看到区别了吧!对于普通函数,虽然父类的指针指向了子类的对象,可是调用的仍然是父类的函数,而虚函数则是执行子类中新定义的函数。
spa

3、虚函数和纯虚函数

    学过java的都知道有类和接口两种不同的东西(其实我在装逼,java也就会i++了.*_*!!),纯虚函数就相似于接口,纯虚函数不能在定义类中实现,但应该在可以实例化的子类中实现。定义了纯虚函数的类就要抽象类(记住是抽象类不是虚基类,网上有个逼说是虚基类,此贴竟然还有好多人转发,真是贻害不浅。好吧也许真是虚基类,那就当我是逼吧^_^)。抽象类不可以被实例化。
指针

4、虚继承和虚基类

    虚继承的主要是为了解决多重继承中出现的二义性问题,普通继承若是一个基类经过几条路径继承到了一个派生类中,那么这个派生类将有两个基类的副本,对这些成员的访问将会出现二义性错误。
code

//虚继承是这样的
class A :public vritual B{
....
}

    虚基类:虚基类是指虚继承中的基类,记住不是含有纯虚函数的类(抽象类)
对象

    注意:对于虚基类的初始化即便是是间接继承,在派生类的构造函数中也应该显示的调用其构造函数,不然将调用默认的构造函数(没有参数,若是没有定义本身的构造函数,系统将会定义默认的构造函数,不然没有默认构造函数),若是没有默认构造函数,程序将会出错。继承

5、总结

    虚函数是为了实现多态性,虚基类是为了解决多重继承的二义性问题,除此以外彷佛没有任何关系(惟一有关系也是虚的,因此有关系是假的)。

    虚基类是虚继承中的基类,抽象类是含有纯虚函数的类,二者彻底不一样。

相关文章
相关标签/搜索