深度探索C++对象模型

C式继承

什么时候会产生虚表和指向虚表的指针?

#include <iostream>
using namespace std;

class A{};
class B : public A {};

int main() {
	cout << sizeof(A) << endl;//1 char
	cout << sizeof(B) << endl;//1 char
	return 0;
}

输出:

1
1
请按任意键继续. . .

可以看出普通继承在没有虚函数和虚继承的时候,并不会产生虚表和虚指针

虚函数产生虚表和虚指针

只要一个类有虚函数,为了实现虚函数就要通过虚表和虚表指针

#include <iostream>
using namespace std;

class A
{
	virtual ~A(){}
};
class B
{
	virtual void f() {}
};

int main() {
	cout << sizeof(A) << endl;//1 vptr
	cout << sizeof(B) << endl;//1 vptr
	return 0;
}

输出:

4
4
请按任意键继续. . .

虚表指针是谁设置的?

是构造函数设置的。

默认构造函数是不是一定会创建?

并不是,只有涉及到虚函数设置虚表的时候编译器才一定会产生构造函数;

同理,因为要设置虚表指针所以拷贝构造函数也会被编译器生成出来;

此时memcpy是危险的,不可取的,因为会复制错误的虚表指针。

对于C那种struct纯基本类型的数据成员结构体是不会产生构造函数的。

Data语义学

class X { };
class Y : public virtual X { };
class Z : public virtual X { };
class A : public Y, public Z { };

类型

编译器A

Visual C++

X

1 = sizeof(X) 1byte char安插用以在内存中区分两个object

1 = sizeof(X) 1byte char安插用以在内存中区分两个object

Y

8 = sizeof(Y)

8 = char + vptr

8 = (1 + 3(内存对齐)) + 4

4 = sizeof(Y)

4 = vptr

 (不再需要额外的1 byte char)

Z

8 = sizeof(Y)

8 = char + vptr

8 = (1 + 3(内存对齐)) + 4

4 = sizeof(Y)

4 = vptr

(不再需要额外的1 byte char)

A

12 = sizeof(A)

12 = char + vptr1 + vptr2

12 = (1 + 3(内存对齐)) + 4 + 4

8 = sizeof(A)

8 = vptr1 + vptr2

8 = 4 + 4

(不再需要额外的1 byte char)

编译器A                                                Visual C++

字节对齐

#include <iostream>
using namespace std;

class A
{
	char a;
};
class B : public A
{
	char b;
};
class C : public B
{
	char c;
};

int main() {
	cout << sizeof(A) << endl;//1 char
	cout << sizeof(B) << endl;//2 char
	cout << sizeof(C) << endl;//3 char
	return 0;
}

输出:

1
2
3
请按任意键继续. . .

再来看看字节对齐之后,A中增加一个int i

#include <iostream>
using namespace std;

class A
{
	int i;
	char a;
};
class B : public A
{
	char b;
};
class C : public B
{
	char c;
};

int main() {
	cout << sizeof(A) << endl;//2 int
	cout << sizeof(B) << endl;//3 int
	cout << sizeof(C) << endl;//4 int
	return 0;
}

输出:

8
12
16
请按任意键继续. . .

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C++程序员Carea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值