批注:虚函数例子

来源:互联网 发布:绿叶软件翻墙 编辑:程序博客网 时间:2024/05/29 16:46

1 how to print class size ? 

  cout <<sizeof(Derived)<<endl;直接用类名


2 why non-function size is 0, for example : class A { void out() {} } 
c++编译完之后是变成c的函数调用形式. 对于函数是不属于任何类的
out 不再class A的空间。编译的时候变成A_out_int( class name ,function name,parameters...) ;B_out1_char(class name,function name,parameter,...) etc.
这样所有类的所有non-virtual函数,在编译的时候,变成子函数集合,然后run的时候每个对象又不一样,因为每个对象通过this指针,带着自己的数据进来。
走一遍这个函数,执行完成,这样每个对象调用同一个函数,但是没有对象又不同的执行结果。类似c的函数调用.

3 why virtual function size is 8. 64bit机 virtual 函数指针是8字节。32bit机 virtual 函数指针是4字节。
class A
{
  virtual aa(int) {};
  void out(int) {};
}
c++的类的函数管理是,virtual 属于类. non-virtual 不属于类。
**************************************************************************************************************************

#include  <iostream>

#include <stdio.h>
#include <stdlib.h>
using namespace std;
class Base
{
  public :
    virtual void Print() { cout<<"This is Base"<<endl;}
};
class Base2
{
  public:
    virtual void Print2() {cout <<"This is base2"<<endl;}
};
class Base3
{
  private :
    void Print3() {cout <<"This is base3"<<endl;}
};
class Derived: public Base,public Base2
{
  public:
    void Print() {cout<<"This is Derived"<<endl;}
    void Print2() {cout<<"This is Derived2"<<endl;}
    void Out() {cout<<"This should not be called"<<endl;}
};
typedef void (*Func)();
int main()
{
  Base *pb = new Derived();
  Base *p = new Base();

  pb->Print();

//表示取,类Derive()的大小8,然后+1,即加8个偏移。指向一个int类型的指针。然后取值。然后再指向这个值的地址。即二级指针。

  int* pA = (int*)(*((int*)(pb+1)));
  int* pAB = (int*)(*((int*)pb));
  cout <<sizeof(Base)<<endl;
  cout <<sizeof(*pb)<<endl;
  cout <<sizeof(Derived)<<endl;
  cout <<sizeof(Base3)<<endl;
  int *a = (int*)pb;
  int *b =((int*)pb+1);
  int c = *((int*)pb+1);
  //d(*pA) is  save  Device print2 address
  int *d = (int *)(*((int*)pb+1));
  Func pFunc =(Func)*pAB;
  pFunc();
  pFunc =(Func)*pA;
  pFunc();
//why it is wrong below? because PA is int* 类型。所以要先转化成函数指针类型,然后再调用
//  *pA();
  return 0;

}


这个例子不能用一个进程取另一个进程的函数地址。因为进程是虚地址。进程之间是有保护的,不能随便访问。取A的地址0x1234虚地址,在B中它是B的地址上取.

example2:

Main()
{
Typedef void (*ff)();
Ff aa;
aa=(ff)(0x10000);
(*aa)();
}

这个是将函数地址,强制转化成函数指针,然后调用函数指针,执行函数.即跳转到0x10000地址

0 0