虚函数
虚函数本质上意思就是在基类声明这个函数的接口类型,可以在继承时重新编写这个函数的定义,关键在于接口要和基类一样。这样的好处主要是可以用基类的指针和引用调用派生类的方法。
例
#include <iostream>
using namespace std;
class Parent {
public:
virtual void f() {
cout << "A::f()" << endl;
}
};
class Child : public Parent {
public:
void f() {
cout << "B::f()" << endl;
}
};
int main()
{
Parent *p = new Child();
p->f();
return 0;
}
// or quote
// int main()
// {
// Child b;
// Parent &a = b;
// a.f();
// return 0;
// }
输出:
B::f()
如果不加 virtual
则输出为:
A::f()
关于虚函数表的问题:
#include <iostream>
using namespace std;
class X {
int i;
virtual void f();
virtual void g();
};
int main()
{
cout << sizeof(X) << ' ' << sizeof(int *) << endl;
return 0;
}
问题由这段代码引出,输出为:
16 8
[参考文章]()
每个有虚函数的类都有一个虚函数表,每个该类的实例(对象)都有一个指向虚表的指针,一个指针的大小为 8 Bytes。
然后一个 int
的大小为 4 Bytes,加起来等于 12,那为什么会是 16 呢?
计组小测有一道题是内存对齐,我错了,于是这提醒我了,我计组学得好烂,该努力了(bushi),更重要的是这提醒我了,为了方便机器读取,C++在编译的时候应该是进行了内存对齐的,于是一个 int
也是用了 8 Bytes 来储存。
为了验证猜想,又增加了一个 int
和两个 int
进行验证,结果分别为 16
和 24
。初步说明我的猜想正确,要严格证明我的猜想正确很麻烦,我大概是没有那能力的,就不严格证明了。
纯虚函数
纯虚函数的声明:
class Abstract {
public:
virtual void f() = 0;
};
作用和虚函数差不多,定义好一个接口,但在 Abstract
类中不对这个方法进行实现,而是在继承这个类的时候派生类必须实现这个方法。区别在于含有纯虚函数的类被称为抽象类,抽象类不能进行实例化,即没法 new 一个抽象类的对象。继承该抽象类的派生类中必须进行抽象类中纯虚函数的实现。
叨叨几句... NOTHING