C++ 虚函数、纯虚函数笔记

C++ 虚函数、纯虚函数笔记

虚函数

C++的虚函数主要作用是“运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现。子类可以重写父类的虚函数实现子类的特殊化。

虚函数关键字 “virtual”。

多态示例:

#include <iostream>
#include <string>

using namespace std;

// 父类 A
class A
{
public:
    // 默认实现,使用 virtual 关键字表示这是一个虚函数
    virtual void virtualFunction()
    {
        cout << "A:virtual function." << endl;
    }
};

// 子类 B
class B: public A
{
public:
    // 重写父类函数
    void virtualFunction()
    {
        cout << "B:virtual function." << endl;
    }
};

// 子类 C
class C : public A
{
public:
    // 重写父类函数
    void virtualFunction()
    {
        cout << "C:virtual function." << endl;
    }
};

int main(int argc, char** argv)
{
    // 使用多态必须用指针创建对象
    A * a1 = new A;
    A * a2 = new B;
    A * a3 = new C;

    // 调用
    a1->virtualFunction();
    a2->virtualFunction();
    a3->virtualFunction();

    system("pause");
    return 0;
}

运行结果:

A:virtual function.
B:virtual function.
C:virtual function.
Press any key to continue . . .

可以看到,使用new创建出A、B、C三种对象,用父类指针A *指向,则函数调用的结果就是各个对象内部的各自实现。这就是“多态”,指针指向谁,就调用谁的方法。

普通函数

和虚函数相比较而言,普通函数前不需要加关键字 “virtual” ,这样就不会有多态效果。

只会根据指针或引用的“字面值”类对象,调用自己的普通函数。普通函数是父类为子类提供的“强制实现”。因此,在继承关系中,子类不应该重写父类的普通函数,因为函数的调用至于类对象的字面值有关。

虚函数和普通函数比较:

#include <iostream>
#include <string>

using namespace std;

// 父类 A
class A
{
public:
    // 默认实现,使用 virtual 关键字表示这是一个虚函数
    virtual void virtualFunction()
    {
        cout << "A:virtual function." << endl;
    }

    // 普通函数,没有 virtual 关键字
    void normalFunction()
    {
        cout << "A:normal function." << endl;
    }
};

// 子类 B
class B: public A
{
public:
    // 重写父类虚函数
    void virtualFunction()
    {
        cout << "B:virtual function." << endl;
    }

    // 重载父类普通函数
    void normalFunction()
    {
        cout << "B:normal function." << endl;
    }
};

// 子类 C
class C : public A
{
public:
    // 重写父类虚函数
    void virtualFunction()
    {
        cout << "C:virtual function." << endl;
    }

    // 重载父类普通函数
    void normalFunction()
    {
        cout << "C:normal function." << endl;
    }
};

int main(int argc, char** argv)
{
    // 使用多态必须用指针创建对象
    A * a1 = new A;
    A * a2 = new B;
    A * a3 = new C;

    // 调用虚函数,多态效果
    a1->virtualFunction();
    a2->virtualFunction();
    a3->virtualFunction();

    cout << "==========" << endl;

    // 调用普通函数
    a1->normalFunction();
    a2->normalFunction();
    a3->normalFunction();

    system("pause");
    return 0;
}

运行结果:

A:virtual function.
B:virtual function.
C:virtual function.
==========
A:normal function.
A:normal function.
A:normal function.
Press any key to continue . . .

可以看出,普通函数调用并没有多态效果,只要是A类的指针,无论指向A类本身或者A类的子类,调用的都是A类内部实现的函数。

纯虚函数

C++中包含纯虚函数的类,被称为是“抽象类”。抽象类不能使用new出对象,只有实现了这个纯虚函数的子类才能new出对象。C++中的纯虚函数更像是“只提供申明,没有实现”,是对子类的约束,是“接口继承”。C++中的纯虚函数也是一种“运行时多态”。

纯虚函数示例代码:

#include <iostream>
#include <string>

using namespace std;

// 父类 A
class A
{
public:
    // 默认实现,使用 virtual 关键字表示这是一个虚函数
    virtual void virtualFunction()
    {
        cout << "A:virtual function." << endl;
    }

    // 普通函数,没有 virtual 关键字
    void normalFunction()
    {
        cout << "A:normal function." << endl;
    }

    // 纯虚函数,没有实现,声明和虚函数声明类似,但要在后面加上 "= 0" 
    virtual void pureVirtualFunction() = 0;
};

// 子类 B
class B: public A
{
public:
    // 重写父类虚函数
    void virtualFunction()
    {
        cout << "B:virtual function." << endl;
    }

    // 重载父类普通函数
    void normalFunction()
    {
        cout << "B:normal function." << endl;
    }

    // 纯虚函数实现
    void pureVirtualFunction() 
    {
        cout << "B:pure virtual function." << endl;
    }
};

// 子类 C
class C : public A
{
public:
    // 重写父类虚函数
    void virtualFunction()
    {
        cout << "C:virtual function." << endl;
    }

    // 重载父类普通函数
    void normalFunction()
    {
        cout << "C:normal function." << endl;
    }

    // 纯虚函数实现
    void pureVirtualFunction()
    {
        cout << "C:pure virtual function." << endl;
    }
};

int main(int argc, char** argv)
{
    // 使用多态必须用指针创建对象
    // A * a1 = new A;  // A为纯虚函数,不能使用 new 关键字创建对象,编译出错
    A * a2 = new B;
    A * a3 = new C;

    // 调用虚函数,多态效果
    a2->virtualFunction();
    a3->virtualFunction();

    cout << "==========" << endl;

    // 调用普通函数
    a2->normalFunction();
    a3->normalFunction();

    cout << "==========" << endl;

    // 调用纯虚函数
    a2->pureVirtualFunction();
    a3->pureVirtualFunction();

    system("pause");
    return 0;
}

运行结果:

B:virtual function.
C:virtual function.
==========
A:normal function.
A:normal function.
==========
B:pure virtual function.
C:pure virtual function.
Press any key to continue . . .

结果表明,纯虚函数也可以实现多态效果。和虚函数的不同在于父类A不提供函数实现,父类A也不能使用new关键字实例化,一般纯虚函数常常在类接口(interface)定义中使用。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值