虚函数有关问题分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 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));
	//不带虚函数类的大小

}

结果:

猜你喜欢

转载自blog.csdn.net/u014595589/article/details/82347218