版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014595589/article/details/82347218
#include<stdio.h>
#include<iostream>
using namespace std;
class FOO
{
public:
void func1(){
printf("func1\n");
};
virtual void func11(){
printf("func11\n");
}
void func2(){
printf("func2\n");
}
virtual void func3(){
printf("func3:%d\n",data1);
}
int data1;
static int data2;
};
int FOO::data2=1;
class aFOO:public FOO{
public:
void virtual func1(){
printf("afunc1\n");
}
void func11(){
printf("afunc11\n");
}
void func2(){
printf("afunc2\n");
}
void func3(){
printf("afunc3:%d\n",data1);
}
virtual void func4(){
printf("afunc4\n");
}
};
class bFOO:public aFOO{
public:
void func1(){
printf("bfunc1\n");
}
void func11(){
printf("bfunc11\n");
}
void func2(){
printf("bfunc2\n");
}
void func3(){
printf("bfunc3:%d\n",data1);
}
void func4(){
printf("bfunc4\n");
}
};
int main(void)
{
FOO *p=new FOO();
FOO *t=new aFOO();
FOO *s=new bFOO();
cout<<"带有虚函数类的大小"<<endl;
cout<<sizeof(FOO)<<endl;
cout<<sizeof(aFOO)<<endl;
cout<<sizeof(bFOO)<<endl;
cout<<"虚函数指针改变前的情况"<<endl;
p->data1=0;
p->func1();
p->func2();
p->func11();
p->func3();
t->data1=1;
t->func1();
t->func11();
t->func3();
((aFOO *)t)->func4();
s->data1=2;
s->func1();
((aFOO *)s)->func1();
s->func2();
s->func11();
((aFOO *)s)->func11();
s->func3();
((aFOO *)s)->func4();
cout<<"虚函数指针改变后的情况"<<endl;
int *tt = (int *)(t);
int *ss = (int *)(s);
tt[0] = ss[0];
p->data1=0;
p->func1();
p->func2();
p->func11();
p->func3();
t->data1=1;
t->func1();
t->func11();
t->func3();
((aFOO *)t)->func4();
s->data1=2;
s->func1();
s->func2();
s->func11();
s->func3();
FOO *n=(FOO*) malloc(sizeof(FOO));
n->data1=1;
n->data2=2;
cout<<n->data1<<endl;
cout<<n->data2<<endl;
//n->func11();//错误
}
输出结果:
分析:
(1)malloc和new的区别,malloc只分配内存,new不仅分配内存,还执行构造函数。
(2)如果一个类中包含了虚函数,那么它的每个对象就有一个虚函数表,用一个指针vptr指向这个虚表,虚表中的每一项指向一个虚函数(你上面的例子只有一个虚函数,所以虚表就一项)
(3)这个虚表的创建是在构造函数中完成的(这个过程我们看不到)
(4)https://blog.csdn.net/haoel/article/details/1948051
(5)要想实现虚函数的特性,必须将基类函数定义为虚函数,带有虚函数的子类函数不加virtual修饰符也具有虚函数的特性
#include<stdio.h>
class D{};
class E{int c;};
class A{
public:
virtual f1(){
printf("A::f1()\n");
}
f2(){
f1();
}
};
class B:public A{
public:
f1(){
printf("B::f1()\n");
}
f2(){
f1();
}
};
void main(){
A *a=new B();
a->f2();
A &aa=B();
aa.f2();
A a3=B();
//调用拷贝构造函数
a3.f2();
A *a4=&B();
a4->f2();
printf("%d\n",sizeof(D));
//空类大小是1
printf("%d\n",sizeof(E));
//不带虚函数类的大小
}
结果: