重温《Inside The C++ Object Model》(1) –关于对象

C/C++ 编程风格

//1.C风格(结构化程序设计):数据和函数(操作)没有任何关联性
typedef struct Point3d
{
float x;
float y;
float z;
} Point3d_t;

void
Point3d_print(const Point3d_t *pd)
{
printf("%g, %g, %g
", pd->x, pd->y, pd->z);
}

//2.基于对象(Object-Base):提供抽象数据类型(ADT)来支持封装
class Point3d
{
friend ostream &operator<<(ostream &os, const Point3d &pt);
public:
Point3d(float x = 0.0, float y = 0.0, float z = 0.0):
_x(x), _y(y), _z(z) {}

float x()
{
return _x;
}
float y()
{
return _y;
}
float z()
{
return _z;
}

void x(float xval)
{
_x = xval;
}

//etc…

private:
float _x;
float _y;
float _z;
};

inline ostream &
operator<<(ostream &os, const Point3d &pt)
{
return os << "( " << pt._x << ", " << pt._y << ", "
<< pt._z << " )";
}

//3.面向对象(Object-Oriented-Model):提供继承和多态
class Point
{
public:
Point(float x = 0.0):
_x(x) {}

float x()
{
return _x;
}

void x(float xValue)
{
_x = xValue;
}

protected:
float _x;
};

class Point2d : public Point
{
public:
Point2d(float x = 0.0, float y = 0.0):
Point(x), _y(y) {}

float y()
{
return _y;
}
void y(float yValue)
{
_y = yValue;
}

protected:
float _y;
};

class Point3d : public Point2d
{
friend inline ostream &
operator<<(ostream &os, const Point3d &pt);

public:
Point3d(float x = 0.0, float y = 0.0, float z = 0.0):
Point2d(x, y), _z(z) {}

float z()
{
return _z;
}
void z(float zValue)
{
_z = zValue;
}

private:
float _z;
};

inline ostream &
operator<<(ostream &os, const Point3d &pt)
{
return os << "( " << pt._x << ", " << pt._y << ", "
<< pt._z << " )";
}

//4.面向泛型:提供模板提供类型无关化的编程风格
//示例(1):仅提供类型参数化
template <typename Type>
class Point3d
{
public:
Point3d(Type x = 0.0, Type y = 0.0, Type z = 0.0):
_x(x), _y(y), _z(z) {}

Type x()
{
return _x;
}
Type y()
{
return _y;
}
Type z()
{
return _z;
}

void x(const Type &xval)
{
_x = xval;
}

//etc…

private:
Type _x;
Type _y;
Type _z;
};

//示例(2):同时提供类型和数目(int dim)参数化
template <typename Type, int dim>
class Point
{
public:
Point() {}
Point(Type coordes[dim])
{
for (int index = 0; index < dim; ++index)
{
_coordes[index] = coordes[index];
}
}

const Type &operator[](int index) const
{
assert(index < dim && index >= 0);
return _coordes[index];
}

private:
Type _coordes[dim];
};

template <typename Type, int dim>
inline ostream &operator<<(ostream &os, const Point< Type, dim > &pt)
{
os << "( ";
for (int i = 0; i < dim; ++i)
os << pt[i] << ", ";
os << ")";
return os;
}

//测试
int array[] = {11,12,333};
Point<int, 3> point(array);
cout << point << endl;
cout << point[2] << endl;

小结:C++加上封装的布局本钱

(1)3个data-member[数据成员]直接内含在每个class-object[对象]当中,犹如C-Struct1样;

(2)Member-function虽然存在于class的声明中, 却不出现在object当中, 每个non-inline member function[非inline的成员函数]只会诞生1个函数实体;

(3)而inline member function会在其每个使用者身上产生1个函数实体.

 

C++对象模型

1.所有的数据成员(static 数据成员除外)寄存在每个对象当中;

2.[1]static 数据成员,[2]成员函数(不管是static/non-static)寄存在所有对象以外;

3.对virtual-functions, 每个对象都有1个vptr(指向1个vtbl(包括type_info object, virtual functions)).

因此:内存中对象的大小

(1)其non-static data member 的总和大小

(2)加上任何alignment(内存对其)的需求而弥补上去的空间[可能存在于members中间, 也可能存在于集合体边界];

(3)加上支持virtual[vptr]而由内部产生的任何额外负担.

//测试
class Point1
{
};

class Point2
{
private:
int number;
};

class Point3
{
public:
Point3(int _number = 0): number(_number) {}
~Point3() {}
static void showCount()
{
std::cout << "Point3_count = " << Point3_count << std::endl;
}

private:
static int Point3_count;

private:
int number;
};

class Point4
{
public:
virtual ~Point4();

private:
int number;
};

int main()
{
cout << sizeof(Point1) << endl;
cout << sizeof(Point2) << endl;
cout << sizeof(Point3) << endl;
cout << sizeof(Point4) << endl;
}

对象在内存中的布局

Derived Class 的Object 和 Pointer布局(以下图)


(其实ZooAnimal subobject 的布局有些毛病, string类型在现代C++中只占4个字节, 因此ZooAnimal subobject所占的内存空间唯一12字节, 而不是图中的16字节)

说明:

(1)pointer & reference 都只需1个字长(x86_32中为4个字节)的空间;

(2)派生类对象中:基类子对象与派生类子对象在内存中的位置是相邻的.

//测试
class ZooAnimal
{
public:
ZooAnimal() {}
virtual ~ZooAnimal() {}
virtual void rotate() {}

protected:
int loc;
string name;
};

class Bear : public ZooAnimal
{
public:
Bear() {}
~Bear() {}

void rotate()
{

}

protected:
enum Dances
{
//…
};
Dances dances_known;
int cell_block;
};

int main()
{
Bear b;
ZooAnimal *pz = &b;
Bear *pb = &b;

cout << "Pointer…" << endl;
cout << sizeof(pz) << endl;
cout << sizeof(pb) << endl;

cout << "
Object…" << endl;
cout << sizeof(*pz) << endl;
cout << sizeof(*pb) << endl;

cout << "
Class…" << endl;
cout << sizeof(ZooAnimal) << endl;
cout << sizeof(Bear) << endl;
}

测试说明:

pb 所涵盖的地址包括了全部Bear Object, 而 pz只包括了Bear Object中的ZooAnimal SubObject!

波比源码 – 精品源码模版分享 | www.bobi11.com
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 本站源码并不保证全部能正常使用,仅供有技术基础的人学习研究,请谨慎下载
8. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!

波比源码 » 重温《Inside The C++ Object Model》(1) –关于对象

3 评论

发表评论

Hi, 如果你对这款模板有疑问,可以跟我联系哦!

联系站长
赞助VIP 享更多特权,建议使用 QQ 登录
喜欢我嘛?喜欢就按“ctrl+D”收藏我吧!♡