虚函数有关问题分析

#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));
	//不带虚函数类的大小

}

结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值