您的位置:首页 > 编程语言 > C语言/C++

C++继承中的内存布局阅读笔记

2010-12-22 15:26 489 查看
2010-12-231.以字母类为例:

class A
{
public:
int a;
};
class B
{
public:
int b;
};
class C:public A, public B
{
public:
int c;
};
void main()
{
C c;
void *p1=(void *)&c;//此处将c对象的地址转换为void类型的指针方便比较
void *p2=(void *)(B *)&c;//先将其转换为B类型指针在转换为void类型,便于比较
void *p3=(void *)(A *)&c;//同上。
cout<<p1<<endl;
cout<<p2<<endl;
cout<<p3<<endl;
cout<<sizeof(c)<<endl;
}


输出结果为:

C->0012ff58

B->0012ff5c

A->0012ff58

说明A和C指向同一位置,B和其相差4字节(一个int型的空间)。

VC++ 按照基类的声明顺序 先排列基类实例数据,最后才排列派生类数据。当然,派生类数据本身也是按照声明顺序布局的.

2.virtual继承

我们可以得到如下关于VC++虚继承下内存布局的结论:

1 首先排列非虚继承的基类实例;
2 有虚基类时,为每个基类增加一个隐藏的vbptr,除非已经从非虚继承的类那里继承了一个vbptr;
3 排列派生类的新数据成员;
4 在实例最后,排列每个虚基类的一个实例。

3.vritual 变量地址的访问

虚继承: 当类有虚基类时,访问非虚基类的成员仍然是计算固定偏移量的问题。然而,访问虚基类的成员变量,开销就增大了 , 因为必须经过如下步骤才能获得成员变量的地址:
1. 获取“虚基类表指针”;
2. 获取虚基类表中某一表项的内容;
3. 把内容中指出的偏移量加到“虚基类表指针”的地址上。

4.虚函数是动态联编的基础,虚函数是成员函数,且为非static的成员函数。

如果某类中的一个成员函数被说明为虚函数,就意味着该成员函数在派生类中可能有不同的定义,就是我们常说的重定义。(这里要注意区分三个概念,一个是重载,一个是重定义,一个是重写)当使用这个成员函数操作指针或引用所标识的对象时,将对该成员函数调用采取动态联编方式,即在运行的时候进行关联或者束定。

动态联编只能通过指针或者引用标志对象来操作虚函数,如果采用一般类型的标志对象来操作虚函数,则将采用静态联编的方式来调用虚函数。

5.

class A
{
public:
virtual void print(){cout<<"A"<<endl;}
void print_1(){cout<<"print_1 in A"<<endl;}
};
class B:public A
{
public:
void print(){cout<<"B"<<endl;}
void print_2(){cout<<"print_2 in B"<<endl;}
};
void print(A *a)
{
a->print();
}
void main()
{
A a;
A *pa=&a;
B b;
B *pb=&b;
A *pab=pb;//此处用A类型的指针指向了B的对象,若print()没有声明为虚函数,则编译时调用哪个print函数由->符号左边来决定.若声明为虚函数,则调用由指针实际指向的类型决定.
pab->print();//若print非虚函数,则输出A,若声明为虚函数,则输出B.

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: