C/C++
文章平均质量分 66
I_Love_CPP
这个作者很懒,什么都没留下…
展开
-
C and C++ Common Knowledge
-1,程序中各段的意义如下:.text(代码段):用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存种的镜像。.data(数据段):数据段用来存放可执行文件中已初始化全局变量,也就是存放程序静态分配的变量和全局变量。.rodata(只读段):该段保存着只读数据,在进程映象中构造不可写的段。.bss(BSS段):BSS段包含了程序中未初始化全局变量,在内存中 bss段是否全部置零依赖于系统原创 2006-03-23 12:59:00 · 1797 阅读 · 0 评论 -
潘凯:C++对象布局及多态实现的探索(六)
虚函数调用 我们再看看虚成员函数的调用。类C041中含有虚成员函数,它的定义如下:struct C041{ C041() : c_(0x01) {} virtual void foo() { c_ = 0x02; } char c_;}; 执行如下代码:C041 obj;PRINT_DETAIL(C041, obj)PRINT_VTABLE_ITEM(obj, 0, 0)转载 2007-09-08 23:27:00 · 1348 阅读 · 0 评论 -
潘凯:C++对象布局及多态实现的探索(一)
前言 本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等。 写这篇文章源于我在论坛上看到的一个贴子。有人问VC使用了哪种方式来实现虚继承。当时我写了一点代码想验证一下,结果发现情况比我想象的要复杂。所以我就干脆认真把相关的问题都过了一遍,并记录成本文。 我对于C++对象模型的知识主要来自于Lippman的书《Inside转载 2007-09-08 23:13:00 · 1320 阅读 · 0 评论 -
C++基本概念在编译器中的实现
对于C++对象模型,相信很多程序员都耳熟能详。本文试图通过一个简单的例子演示一些C++基本概念在编译器中的实现,以期达到眼见为实的效果。 1、对象空间和虚函数 1.1 对象空间 在我们为对象分配一块空间时,例如: CChild1 *pChild = new CChild1(); 这块空间里放着什么东西? 在CChild1没有虚函数时转载 2007-09-09 19:46:00 · 1150 阅读 · 0 评论 -
潘凯:C++对象布局及多态实现的探索(二)
带虚函数的类的对象布局(1) 如果类中存在虚函数时,情况会怎样呢?我们知道当一个类中有虚函数时,编译器会为该类产生一个虚函数表,并在它的每一个对象中插入一个指向该虚函数表的指针,通常这个指针是插在对象的起始位置。所谓的虚函数表实际就是一个指针数组,其中的指针指向真正的函数起始地址。我们来验证一下,定义一个无成员变量的类C040,内含一个虚函数。struct C040{ virtual转载 2007-09-08 23:16:00 · 1216 阅读 · 0 评论 -
潘凯:C++对象布局及多态实现的探索(十一)
菱形结构的虚继承(3) 最后我们看看,如果在上篇例子的基础上,子类及左、右父类都各自定义了自己的虚函数,这时的情况又会怎样。struct C140 : public virtual C041{ C140() : c_(0x02) {} virtual void foo() { c_ = 0x11; } char c_;};struct C160 : public virtual转载 2007-09-08 23:36:00 · 1094 阅读 · 0 评论 -
潘凯:C++对象布局及多态实现的探索(十)
菱形结构的虚继承(2) 我们再看一个例子,这个例子的继承结构和上一篇中是一样的,也是菱形结构。不同的是,每一个类都重写了顶层类声明的虚函数。代码如下:struct C041{ C041() : c_(0x01) {} virtual void foo() { c_ = 0x02; } char c_;};struct C140 : public virtual C041{转载 2007-09-08 23:35:00 · 1164 阅读 · 0 评论 -
潘凯:C++对象布局及多态实现的探索(七)
构造函数中的虚成员函数调用 在构造函数中调用虚成员函数,虽然这是个不很常用的技术,但研究一下可以加深对虚函数机制及对象构造过程的理解。这个问题也和一般直观上的认识有所差异。先看看下面的两个类定义。struct C180{C180() { foo(); this->foo();}virtual foo() {cout }};struct C190 : public C180{C190() {转载 2007-09-08 23:29:00 · 1590 阅读 · 0 评论 -
潘凯:C++对象布局及多态实现的探索(五)
普通成员函数的调用 从这部分开始我们除了利用内存的信息打印来进行探索外,更多的会通过跟踪和观察编译器产生的汇编代码来理解编译器对这些语言特性的实现方式。汇编方面知识的讨论超出了本文的范围,我只对和我们讨论相关的汇编代码进行解析。理解本文要讨论的知识并不需要有很完整的汇编知识,但必须了解起码的概念。 下面我们看看引入虚继承后的影响。为了有所对比我们首先看看普通成员函数的调用情况。 执行如下转载 2007-09-08 23:25:00 · 1193 阅读 · 0 评论 -
潘凯:C++对象布局及多态实现的探索(十三)
代码中所定义类的简单说明C000:空类。C010:带普通成员函数及/或变量的顶层类。C011:带普通成员函数及/或变量的顶层类。C012:带静态成员函数及变量的顶层类。C013:从C010继承的有成员变量及覆盖父类普通成员函数的类。C014:从C011继承的空类。C015:从C010,C011继承的空类。C016:从C015继承带成员函数及/或变量的类。C020:从C010虚继承的带有自己的成员变转载 2007-09-08 23:41:00 · 1194 阅读 · 0 评论 -
潘凯:C++对象布局及多态实现的探索(十二)
后记 结合前面的讨论,我们可以看到,只要牵涉到了虚继承,在访问父类的成员变量时生成的代码相当的低效,需要通过很多间接的计算来定位成员变量的地址。在指针类型转换,动态转型,及虚函数调用时,也需要生成很多额外的代码来调整this指针。象前一篇中对C170对象的obj.foo()和obj.f170()两次调用,传递到两个函数中的this指针居然是不一样的。 前面我们碰到过的怪异行为还有很多,比如偏移转载 2007-09-08 23:38:00 · 1356 阅读 · 0 评论 -
潘凯:C++对象布局及多态实现的探索(九)
菱形结构的虚继承 这次我们看看菱形结构的虚继承。虚继承的引入本就是为了解决复杂结构的继承体系问题。上一篇我们在讨论虚继承时用的是一个简单的继承结构,只是为了打个铺垫。 我们先看看这几个类,这是一个典型的菱形继承结构。C100和C101通过虚继承共享同一个父类C041。C110则从C100和C101多重继承而来。struct C041{C041() : c_(0x01) {}virtual转载 2007-09-08 23:32:00 · 1274 阅读 · 0 评论 -
潘凯:C++对象布局及多态实现的探索(四)
类型动态转换和类型强制转换 为了验证前面提到过的类型动态转换(即dynamic_cast转换),以及对象类型的强制转换。我们利用前面定义的C041、C042及C082类来进行验证。 运行下列代码:c082.C041::c_ = 0x05;PRINT_VTABLE_ITEM(c041, 0, 0)PRINT_DETAIL(C041, ((C041)c082))PRINT_VTABLE_ITEM(转载 2007-09-08 23:21:00 · 1217 阅读 · 0 评论 -
组合类型的优化
1.结构:(1)内存的考虑: struct A{ char a; long b; char c; long d;}; struct B{ char a; char c; long b; long d;}; #pragma pack(push,1) // 1 就是sizeof(char)的值 struct C{ char a; long b; c原创 2006-04-04 15:48:00 · 1239 阅读 · 0 评论 -
类从结构继承的一个问题
Struct A{ ... }; Class MyClass : public A { MyClass(); virtual ~MyClass();//用virtual有时会出错,因为它在内存中会添加一个虚函数表,造成 //内存地址出错。 }原创 2006-04-04 15:43:00 · 1038 阅读 · 0 评论 -
潘凯:C++对象布局及多态实现的探索(八)
普通的虚继承 下面我们来看虚继承。首先看看这C020类,它从C010虚继承:struct C010{ C010() : c_(0x01) {} void foo() { c_ = 0x02; } char c_;};struct C020 : public virtual C010{ C020() : c_(0x02) {} char c_;}; 运行如下代码转载 2007-09-08 23:30:00 · 1329 阅读 · 0 评论