虚函数和纯虚函数

虚函数和纯虚函数

定义

虚函数

类中,声明函数前有virtual关键字的为虚函数

1
2
3
class A {
virtual void example();
}

纯虚函数

纯虚函数的声明格式如下:

1
2
3
class A {
virtual void example() = 0;
}

多态

同样的入口,调用不同的函数。

从基类的对象作为入口,通过变换指针地址,调用派生类的函数。

基类的成员函数应该是虚函数,派生类中的成员函数可以是虚函数也可以是普通函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 多态的通常实现。
#include <iostream>
using namespace std;
class A {
   public:
    virtual void Print() { cout << "A::Print" << endl; }
};
class B : public A {
   public:
    virtual void Print() { cout << "B::Print" << endl; }
};
class D : public A {
   public:
    virtual void Print() { cout << "D::Print" << endl; }
};
class E : public B {
    virtual void Print() { cout << "E::Print" << endl; }
};
int main() {
    A a;
    B b;
    D d;
    E e;
    A* pa = &a;
    B* pb = &b;
    pa->Print();  // 多态, a.Print()被调用,输出:A::Print
    pa = pb;      // 基类指针pa指向派生类对象b
    pa->Print();  // b.Print()被调用,输出:B::Print
    pa = &d;      // 基类指针pa指向派生类对象d
    pa->Print();  // 多态, d. Print ()被调用,输出:D::Print
    pa = &e;      // 基类指针pa指向派生类对象e
    pa->Print();  // 多态, e.Print () 被调用,输出:E::Print
    return 0;

}

通过基类引用实现多态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
class A {
   public:
    virtual void Print() { cout << "A::Print" << endl; }
};
class B : public A {
   public:
    virtual void Print() { cout << "B::Print" << endl; }
};
void Printlnfo(A& r) {
    r.Print();  // 多态,调用哪个Print,取决于r引用了哪个类的对象
}
int main() {
    A a;
    B b;
    Printlnfo(a);  // 输出 A::Print
    Printlnfo(b);  // 输出 B::Print
    return 0;
}

函数重写和函数重载

函数重写(override)

派生类中重新定义函数,只有函数体中实现的内容可以和被重写的函数不同。

基类被重写的函数应该是虚函数或纯虚函数

函数重载

函数同名,但参数的个数类型_,_顺序 可以不同,调用时根据参数列表选择函数。

重载不关心函数返回类型。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class A {
public:
virtual void intro(){
cout<<"I am a funtion of class A.";
}
};

class B : public A {
public:
void intro(){
cout<<"I am a funtion of class B.";
}

void intro(int a){
cout<<"I am a funtion of class B with input param int.";
}
}

int main(void)
{
std::shared_ptr<A> a = std::make_shared<A>();
//! 调用A::intro()
a->intro();

a.reset(new B());
//! 调用B::intro(), B::intro()重写了A::intro()
a->intro();

B b;
//! 调用B::intro(int a), B::intro(int a)重载了B::intro()
b.intro(1);

return 0;
}
作者

Erial

发布于

2022-09-19

更新于

2023-02-19

许可协议

评论