c++中指向类数据成员的指针

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">首先提出几个问题:</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">1、怎么获得数据成员的偏移量?</span>

2、如果类中有虚函数,类的布局是怎么样?vptr是放在对象内存的开始处还是结尾处,还是什么地方?(当然具体的编译器实现不同)

在这里在vs2010上进行几个简单的测试

测试例子1

Point3d.h文件
#pragma once
class Point3d
{
public:
	Point3d(void);
	~Point3d(void);
private:
public:

	float x;
	float y;
	float z;
};
test.cpp文件
<pre name="code" class="cpp">#include <iostream>
#include <cstdio>
#include "Point3d.h"
using namespace std;

int  main(void)
{
	printf("%d, %d, %d\n", &Point3d::x, &Point3d::y, &Point3d::z);
	cout << &Point3d::x << endl << &Point3d::y << endl << &Point3d::z << endl;
	return 0;
}
输出结果:

 
0, 4, 8
1
1
1

上例中main函数中的&Point3d::x、&Point3d::y、&Point3d::z所求分别为x、y、z在类对象中的偏移量(offset)。偏移量的实现大多数编译器是通过整数来实现。这也表明指向类的数据成员的指针就是一个偏移量,并不是指向内存的具体地址。《深入理解c++对象模型》中讲到,对于偏移量,有些编译器会将数据成员的偏移量加上1。这样做的目的是为了区分一个“没有指向任何数据成员的”指针和一个指向“第一个数据成员的指针”(上面说了指向数据成员的指针也是偏移量,有些编译器实现为整数)。

但是可以看到vs2010中,并没有将偏移量增加1。所以说,使用printf的输出结果为0,4,8。而使用,cout的输出却都为1,这是因为iostream并没有重载成员指针类型。所以编译器在这里进行了转化,输出结果全为1。


如果类中有虚函数是,在vs2010中vptr的布局是怎么样的呢?

注意我只将Point3d类稍作修改,将它的析构函数声明为虚函数

#pragma once
class Point3d
{
public:
	Point3d(void);
	virtual ~Point3d(void);
private:
public:

	float x;
	float y;
	float z;
};
<pre name="code" class="cpp">输出结果:
4, 8, 12
1
1
1

 

从这个例子可以看出,vs2010中vptr放在类对象的内存的开始处。所以三个数据成员的偏移量分别是4 、8 、12。




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值