/************************
//object.cpp
************************/
#include <iostream>
#include <string>
using namespace std;
typedef void (*func_pointer)(void);
class Animal
{
public:
virtual void get_vptr_addr()
{
cout<<" Animal::this: "<< this << endl;
};
virtual void get_vtbl_addr()
{
cout<<" Animal::vtbl:"<< this <<endl;
};
void call_first_virtual_func()
{
fun = (func_pointer)* ((int*)*(int*)this);
cout<< "Animal::call_first_virtual_func:" << fun <<endl;
fun();
}
public:
func_pointer fun;
private:
int age;
string name;
};
class Bear:public Animal
{
public:
Bear(){};
virtual void get_vptr_addr()
{
cout<<" Bear::this: "<< this <<endl;
};
void call_first_virtual_func()
{
fun = (func_pointer)*((int*)*(int*)this);
cout<< "Bear::call_first_virtual_func:" << ((int*)*(int*)this) <<endl;
fun();
}
void call_second_virtual_func()
{
fun = (func_pointer)*((int*)*(int*)this + 2);
cout<< "Bear::call_second_virtual_func:" << ((int*)*(int*)this + 2) <<endl;
fun();
}
};
int main()
{
//object size:
//1. nonstatic member data;
//2. virtual point
//3. struct align
Animal a;
Bear b;
Animal *pa = &b;
cout << "point size: "<<sizeof(pa) <<endl;
cout << "int size: "<<sizeof(int) <<endl;
cout << "string size: "<<sizeof(string) <<endl;
cout << "Animal size: "<<sizeof(a) <<endl;
//polymorphism
a.call_first_virtual_func();
b.call_first_virtual_func();
cout<<"vtabl: "<<sizeof((int*)*(int*))<<endl;
cout<<"vtbl fisrt func:"<<((int*)*(int*)&b)<<endl;
cout<<"vtbl second func:"<<((int*)*(int*)&b + 1)<<endl;
b.call_second_virtual_func();
return 0;
}
一:关于对象大小
只有非静态成员变量才会放在类对象中, 所以类对象大小由三个方面组成
1. 非静态成员大小的总和
2. 如果存在虚函数,则存在一个指向虚函数表的指针ptr.
3. 在加上由对齐产生的额外空间
二: 关于多态
只有指针和引用才会支持多态.
虚函数表是属于类的所有对象,每个对象存在一个vptr指向这张表.
目前所知,vptr总是在对象内存布局的最前面.
三:初始化列表
如果在构造函数中对成员变量初始化的话,实际进行的是赋值操作,
因为在进入构造函数之前,编译器调用成员变量的默认构造函数对成员变量进行了初始化。
对于内置类型,在那里进行初始化无所谓,因为效率差不多。
但对于自定义类型,通过初始化列表进行初始化,只需调用一次拷贝构造函数,
而在构造函数中初始化,需要调用一次默认构造函数和一次赋值操作。
四:疑问
改程序打印出指针的大小占8个字节,但是第二个虚函数的地址却是((int*)*(int*)this + 2),为什么不是((int*)*(int*)this + 1)求大神解答.