C++ 虚函数

在类的定义中,前面有virtual 关键字的成员函数就是虚函数。

1)virtual 关键字只用在类定义里的函数声明中,写函数体是不用。

2)构造函数和静态成员函数不能是虚函数。

虚函数的作用同函数重载一样,也是为了实现多态性。

 

以下示例中 A 和 B 定义了相同接口,分别调用时,输出不同。

class A {
public:
    void print() { cout << "a" << endl; }
};

class B: public A {
public:
    void print() { cout << "b" << endl; }
};

int main()
{
    A a;
    B b;
    a.print();
    b.print();

    return 0;
}

 

但以上并不是多态。

多态的表现形式一:

1)派生类的指针可以赋给基类指针。

2)通过基类指针调用基类和派生类中的同名虚函数时:

(1)若该指针指向一个基类的对象,那么被调用的是基类的虚函数

(2)若该指针指向一个派生类的对象,那么被调用的是派生类的虚函数。

这种机制就叫做“多态”

多态的表现形式二:

1)派生类的对象可以赋给基类引用

2)通过基类引用调用基类和派生类中的同名虚函数时:

(1)若该引用引用的是一个基类的对象,那么被调用是基类的虚函数

(2)若该引用引用的是一个派生类的对象,那么被调用的是派生类的虚函数。

这种机制也叫做“多态”

 

把以上代码的 main() 函数改一下:

int main()
{
    A a;
    B b;
    A *pa = &a;
    A *pb = &b;
    pa->print();
    pb->print();

    return 0;
}

结果如下:

 

问题来了,pb 明明指向的是 class B 的对象,但调用的却是 class A 的 print() 函数。

这不是我们所期望的结果,解决这个问题就需要用到虚函数。修改A、B的定义如下:

class A {
public:
    virtual void print() { cout << "this is a" << endl; }
};

class B: public A {
public:
    virtual void print() { cout << "this is b" << endl; }
};

结果如下:

 

当 main() 修改为引用方式时,结果同上:

int main()
{
    A a;
    B b;

    A &ra = a;
    ra.print();

    A &rb = b;
    rb.print();

    return 0;
}

 

类A的成员函数 print() 已经成了虚函数,并且类B的成员函数 print() 也成了虚函数,当基类的成员函数高为 virtual,

其派生类的同名函数也会自动变成虚函数(加不加virtual都可以)。所以类B的 print() 也成了虚函数。

 

总之,指向基类的指针在操作它的多态对象时,会根据不同的类对象,调用其相应的函数,这个函数就是虚函数。

而不是根据自身类对象的类型调用相应的函数。

posted @ 2015-06-23 10:30  阿青1987  阅读(165)  评论(0编辑  收藏  举报