随笔分类 -  C++

摘要:printf背后的故事 说起编程语言,C语言大家再熟悉不过。说起最简单的代码,Helloworld更是众所周知。一条简单的printf语句便可以完成这个简单的功能,可是printf背后到底做了什么事情呢?可能很多人不曾在意,也或许你比我还要好奇!那我们就聊聊printf背后的故事。 一、printf的代码在哪里? 显然,Helloworld的源代码需要经过编译器编译,操作系统的加载才能正确执行。而编译器包含预编译、编译、汇编和链接四个步骤。 #include int main() { printf("Hello World !\n"); return 0; } ... 阅读全文
posted @ 2014-01-14 21:54 Florian 阅读(20499) 评论(10) 推荐(12) 编辑
摘要:命令行下的树形打印最近在处理代码分析问题时,需要将代码的作用域按照树形结构输出。问题的原型大概是下边这个样子的。图中给了一个简化的代码片段,该代码片段包含5个作用域:全局作用域0、函数fun作用域1、if语句作用域2、else语句作用域3和函数main作用域4。代码作用域有个显著的特点就是具有树形结构,全局作用域作为树根,函数作用域则是其子节点,而局部作用域则是函数作用域的子节点,以此类推。如果要在命令行下输出作用域的组织结构,则是目录树的形式。将树进行命令行打印并非一件难事,使用的是树的递归深度遍历的思想。代码片段如下:/*树形打印作用域root:子树根blk:缩进次数*/voidprint 阅读全文
posted @ 2013-12-15 22:31 Florian 阅读(8220) 评论(2) 推荐(0) 编辑
摘要:关于vtordisp知多少?我相信不少人看到这篇文章,多半是来自于对标题中“vtordisp”的好奇。其实这个关键词也是来源于我最近查看对象模型的时候偶然发现的。我是一个喜欢深究问题根源的人(有点牛角尖吧),所以当我第一次发现vtordisp的时候,我也是很自然的把它输进google查找相关资料,但是结果令我不太满意。不过,即使如此,我还是把与它相关的资料整理如下,并结合自己的理解和大家分享一下,希望能共同学习进步。首先从产生“vtordisp”问题的那个例子开始。classBase{public:intbase;virtualvoidfun(){}};classDer:virtualpub. 阅读全文
posted @ 2013-01-14 17:17 Florian 阅读(2458) 评论(2) 推荐(1) 编辑
摘要:虚函数与虚继承寻踪封装、继承、多态是面向对象语言的三大特性,熟悉C++的人对此应该不会有太多异议。C语言提供的struct,顶多算得上对数据的简单封装,而C++的引入把struct“升级”为class,使得面向对象的概念更加强大。继承机制解决了对象复用的问题,然而多重继承又会产生成员冲突的问题,虚继承在我看来更像是一种“不得已”的解决方案。多态让对象具有了运行时特性,并且它是软件设计复用的本质,虚函数的出现为多态性质提供了实现手段。如果说C语言的struct相当于对数据成员简单的排列(可能有对齐问题),那么C++的class让对象的数据的封装变得更加复杂。所有的这些问题来源于C++的一个关键字 阅读全文
posted @ 2013-01-14 09:24 Florian 阅读(17915) 评论(27) 推荐(25) 编辑
摘要:对象的传值与返回说起函数,就不免要谈谈函数的参数和返回值。一般的,我们习惯把函数看作一个处理的封装(比如黑箱),而参数和返回值一般对应着处理过程的输入和输出。这种情况下,参数和返回值都是值类型的,也就是说,函数和它的调用者的信息交流方式是用过数据的拷贝来完成,即我们习惯上称呼的“值传递”。但是自从引入了“引用”的概念后,函数的传统模型就不再那么“和谐”了。引用的传递可以允许函数和调用者共享数据对象,它们之间的信息交流不再使用信息拷贝的方式,而是使用更有效率的信息共享的方式,引用导致函数的参数并有输入和输出的双重功能。然而,事物总有两面性,信息共享带来方便的同时也带来了一定的不安全性。我们这里. 阅读全文
posted @ 2013-01-13 16:47 Florian 阅读(3923) 评论(2) 推荐(0) 编辑
摘要:不要被C++“自动生成”所蒙骗C++对象可以使用两种方式进行创建:构造函数和复制构造函数。假如我们定义了类A,并使用它创建对象。Aa,b;Ac=a;Ad(b);对象a和b使用编译器提供的默认构造函数A::A()创建出来,我们称这种创建方式为对象的定义(包含声明的含义)。对象c和d则是使用已有的对象,通过编译器提供的复制构造函数A::A(const A&)创建,我们称这种创建方式为对象的初始化(包含定义和声明的含义)。可能不少人会把对象的初始化和对象的赋值混淆,比如。c=d;这里把对象d赋值给对象c并非创建新的对象,它不会调用任何构造函数。编译器默认提供的赋值运算符重载函数const A 阅读全文
posted @ 2013-01-12 22:40 Florian 阅读(3669) 评论(6) 推荐(2) 编辑
摘要:从实现装饰者模式中思考C++指针和引用的选择最近在看设计模式的内容,偶然间手痒就写了一个“装饰者”模式的一个实例。该实例来源于风雪涟漪的博客,我对它做了简化。作为一个经典的设计模式,本身并没有太多要说的内容。但是在我尝试使用C++去实现这个模式的实例的时候,出现了一些看似无关紧要但是却引人深思的问题。首先,我想简单介绍一下这个实例的含义。实例的目的是希望通过装饰器类对已有的蛋糕类进行装饰补充,于是按照装饰者模式的设计结构,有类似图1的设计结构。图1 装饰者模式蛋糕类和装饰器类都继承于一个公共的基类,该基类声明了一些公共接口。这里简单的使用getName来返回当前蛋糕的名称,而装饰器类可以对该蛋 阅读全文
posted @ 2012-11-19 20:43 Florian 阅读(2894) 评论(14) 推荐(2) 编辑
摘要:那些陌生的C++关键字学过程序语言的人相信对关键字并不陌生。偶然间翻起了《C++ Primer》这本书,书中列举了所有C++的关键字。我认真核对了一下,竟然发现有若干个从未使用过的关键字。一时间对一个学了六年C++的自己狠狠鄙视了一番,下决心一定要把它们搞明白!图1红色字体给出的是我个人感觉一般大家都会比较陌生的关键字,下边我们逐个学习。图1 C++ 关键字一、typeid从名字直观看来,该关键字应该是获取语言元素的类型ID。其实它和sizeof类似,是一个类型运算符。有时候代码可能需要获取某个变量或者类型的名字,这时候使用typeid就比较合适。使用格式:typeid(int)或typeid 阅读全文
posted @ 2012-11-07 19:06 Florian 阅读(14153) 评论(5) 推荐(5) 编辑