C++必知必会之(11)编译器会在类中放东西
2013-11-19 10:39
232 查看
1、对于一个类而言,并非总是“所见即所得”。
如果一个类声明了一个或多个虚函数,那么编译器将会为该类的每一个对象插入一个指向虚函数表的指针(标准并未保证移动会如此,但所有现有的C++编译器都采用这种方式来实现虚函数机制)。
大多数程序员会假定不同平台之间的虚函数表指针的位置是相同的,因此编写依赖于这种假定的代码。
实际上,有些编译器将指针置于对象的开头,还有一些是在末尾,而且,如果涉及多重继承,若干个虚函数表指针就可能会散布于对象之中。
如果使用了虚拟继承,对象将会通过嵌入的指针、嵌入的偏移或其他非嵌入的信息来保持对其虚基类子对象位置的跟踪。因此,即便类没有声明虚函数,其中还是有可能被插入了一个虚函数表指针!
(不管类的数据成员的声明顺序如何,编译器都被允许(有节制地)重新安排它们的布局)。
可以定义一个POD(朴素的旧式数据)来确保一个类类型想一个C struct重要。
内建的类型,比如int、double或者C struct和union都是POD。
struct S //a POD
{
int a;
double b;
};
2、如果希望复制一个类对象,那么永远都不要使用memcpy这样的标准内存块复制函数(或手工编写的等价代码),
因为这种函数是用来复制存储区,而不是用来复制对象的。
相反,应该使用对象的初始化或赋值操作。对象的构造函数是编译器建立隐藏机制的地方,该隐藏机制实现对象的虚函数以及诸如此类的东西。
将一个对象复制给另一个对象时,必须小心不要覆盖这些内部类的机制。
例如,赋值操作永远不应该改变对象的虚函数表指针的值,它们由构造函数设置,并且在对象整个生命期内保持不变。简单的“比特冲击”可能还会破坏脆弱的内部结构。
另一个常见的问题是假定一个类的特定成员位于对象中给定的位置。
如果一个类声明了一个或多个虚函数,那么编译器将会为该类的每一个对象插入一个指向虚函数表的指针(标准并未保证移动会如此,但所有现有的C++编译器都采用这种方式来实现虚函数机制)。
大多数程序员会假定不同平台之间的虚函数表指针的位置是相同的,因此编写依赖于这种假定的代码。
实际上,有些编译器将指针置于对象的开头,还有一些是在末尾,而且,如果涉及多重继承,若干个虚函数表指针就可能会散布于对象之中。
如果使用了虚拟继承,对象将会通过嵌入的指针、嵌入的偏移或其他非嵌入的信息来保持对其虚基类子对象位置的跟踪。因此,即便类没有声明虚函数,其中还是有可能被插入了一个虚函数表指针!
(不管类的数据成员的声明顺序如何,编译器都被允许(有节制地)重新安排它们的布局)。
可以定义一个POD(朴素的旧式数据)来确保一个类类型想一个C struct重要。
内建的类型,比如int、double或者C struct和union都是POD。
struct S //a POD
{
int a;
double b;
};
2、如果希望复制一个类对象,那么永远都不要使用memcpy这样的标准内存块复制函数(或手工编写的等价代码),
因为这种函数是用来复制存储区,而不是用来复制对象的。
相反,应该使用对象的初始化或赋值操作。对象的构造函数是编译器建立隐藏机制的地方,该隐藏机制实现对象的虚函数以及诸如此类的东西。
将一个对象复制给另一个对象时,必须小心不要覆盖这些内部类的机制。
例如,赋值操作永远不应该改变对象的虚函数表指针的值,它们由构造函数设置,并且在对象整个生命期内保持不变。简单的“比特冲击”可能还会破坏脆弱的内部结构。
另一个常见的问题是假定一个类的特定成员位于对象中给定的位置。
相关文章推荐
- Item 11. 编译器对类的影响(The Compiler Puts Stuff in Classes )
- LCC编译器的源程序分析(11)声明与符号表
- Ubuntu 9.10 下如何安装 Intel 编译器 11系列
- LCC编译器的源程序分析(11)声明与符号表
- LCC编译器的源程序分析(10)(11)
- c++ - 编译器会在类中放东西 & 使用抽象数据
- 11 栈与编译器(一):后缀表达式
- LCC编译器的源程序分析(11)声明与符号表
- 11 栈与编译器(二):括号匹配
- 检查gcc编译器是否C++ 11特性
- 11、SQL Server:绝对经典sql语句查询分类前几条信息 ,并按某字段排序(有点东西没看懂)
- 编译器架构的王者LLVM——(11)深入理解GetElementPtr
- 为啥下东西要这么多积分…………求一个win7 64位能用的c编译器,求教使用
- linux学习(11)文件系统(这一章都是概念性的东西啊,看的人想睡觉....就全都记下来吧)
- 不要太相信编译器哦!有时断点看到的东西和实际不一样!
- 编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异
- [转载]LCC编译器的源程序分析(11)声明与符号表
- 编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异
- 奥运英语[11]北京有很多值得看的东西 There is a lot to see in Beijing.
- Solaris 11 gcc 编译器