C++程序设计之四书五经_第1页
C++程序设计之四书五经_第2页
C++程序设计之四书五经_第3页
C++程序设计之四书五经_第4页
C++程序设计之四书五经_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

登陆 注册新用户 编程爱好者博客 编程爱好者首页 黑羽黑羽 博主介绍博主介绍 博主 黑羽的小窝 r 文章分类文章分类 业界 C 及 C VisualFoxpro 经验心得 网络知识 外挂制作 所有文章 最新评论最新评论 不错 顶一下 虽然内容不是很多 但相信会 最新留言最新留言 暂无内容 填写留言填写留言其它类型时 依然要给出显示强制转换 另外需要注意的是另外需要注意的是 void 类型的指针变量无法直接使用类型的指针变量无法直接使用 引用引用 打印输出打印输出 它唯一的作用就是保存指针值它唯一的作用就是保存指针值 3 四种稍复杂的表达方式四种稍复杂的表达方式 int x xp 1 xp 2 xp 3 xp 4 xp 需要注意的是需要注意的是 x 或或 x 是绝对不允许的是绝对不允许的 阅读全文 2000 评论 0 复制链接 函数模板的使用函数模板的使用 2006 4 16 10 29 00 在 C 未出现 template 概念以前 人们对于完成同样一件任务但有时类型不同的函数 必须写很多遍不同的 版本以适用类型的复杂性 例 int sum int x int y return x y float sum float x float y return x y double sum double x double y return x y 这样程序员将有相当大的一部分时间需要花在这些代码上 直到 C template 概念出来后 这种情况被改 善了 现在人们只需要 template T sum T x T y return x y 在程序运行的过程中 编译器自动 生成 某个类型的函数代码以适应不同的要求 但是有一点必须要注意 似 乎以上的 template 只适应类型相同的情况 阅读全文 2019 评论 0 复制链接 利用利用 C 实现哈夫曼算法实现哈夫曼算法 2006 4 5 23 22 00 我想每个计算机专业的学生或多或少都接触过哈夫曼编码 数据结构中的老问题了 大体就是给出一 些字符 和这些字符的出现频率 让你为这些字符设计一个二进制编码 要求频率最高的字符的编码最短 解决的方法是构造一棵哈夫曼树 二叉树 其基本思路是 每次从这些字符中挑出两个频率最低的 然 后构造一个新的结点 使新结点的左右孩子指针分别指向那两个节点 我想这个大家都很清楚了 我就不 多说了 主要讲下这次我用 C 实现时遇到的问题 首先 我定义了一个哈夫曼树结点 class hNode public friend bool operator hNode n1 hNode n2 定义了大于符号 供优先队列排列使用 hNode string d int i 0 hNode l NULL hNode r NULL left l right r data d value i hNode left hNode right string data 储存的字符串 int value 字符串出现的次数 bool operator hNode n1 hNode n2 return n1 value n2 value 因为只是算法课的小作业 所以我也不准备为 hNode 定义完整的二叉树操作 仅仅只是存放数据的 对象 所以只有一个构造函数 并且所有的 data member 都是公有的 这此写这个算法会遇到大麻烦 主要因为是用了 std priority queue 容器 当时考虑到在哈夫曼中要每 次挑选两个频率最小 即出现次数最小 我那个 hNode 里的 value 是出现的次数 很自然的就想到了 std priority queue 容器 优先队列每次都会弹出队列中权值最高的元素 这个特性无疑是实现哈夫曼算法 的最佳选择 然而因为第一次用 std priority queue 容器 结果出了不少问题 好在最后都一一解决 也学 到了不少东西 初步的设想是这样的 先把所有的 hNode 对象都压入优先队列中去 然后每次弹出两个 组成一个 新的结点 再把新的结点压入队列 重复这一步骤 当队列中只有一个元素时 哈夫曼树也就完成了 像 这样 是错的 可别学 while std priority queue q hNode h1 q top q pop hNode h2 q top q pop hNode r r left h1 r right h2 r value h1 value h2 value q push r 然而遭遇的第一个问题是 STL 的所有容器的的插入都是基于 by value 语义的 也就是要生成一个对 象的副本放在容器中 这样的后果就是 hNode 的 left right 指针都指到不知道什么地方去了 大家可以稍微 画几个图试一下 就知道出了什么问题了 考虑一下后 发现如果队列里存放 hNode 的指针 就不会出 现这个问题了 于是改写成 hNode makeTree priority queue pq hNode p1 NULL hNode p2 NULL hNode r NULL while pq empty p1 pq top pq pop if pq empty r p1 return r p2 pq top pq pop r new hNode r left p1 r right p2 r value p1 value p2 value pq push r return NULL 然而马上遭遇了第二个问题 std priority queue 在判断优先关系的时候 直接比较指针的地址 而不 是指针指向的对象的大小关系 而指针不是类 我没办法重写指针的比较操作 程序陷入了困境之中 std priority queue 默认使用 Greater模板来生成一个 function object 来对元素进行比较 我试图为 Greater写一个 hNode 的特化版本来改变优先队列对 hNode 的比较 然而也没有成功 山重水复疑无路 之时 突然想到为什么不直接为优先队列写一个 function object 来替代 Greater不就可以了吗 赶快写下 如下代码 struct phNodeComp bool operator const hNode 然后把 std priority queue 的申明变为 priority queue hNode vector phNodeComp pq 终于把这个问题给解决了 看样子仅从书本上获得的知识是不牢靠的 一定要自己实践了才会有真正 的认识 阅读全文 2853 评论 0 复制链接 用用 C 实现简单的文件实现简单的文件 I O 操作操作 2006 4 5 23 18 00 文件 I O 在 C 中比烤蛋糕简单多了 在这篇文章里 我会详细解释 ASCII 和二进制文件的输入输 出的每个细节 值得注意的是 所有这些都是用 C 完成的 一 ASCII 输出 为了使用下面的方法 你必须包含头文件 译者注 在标准 C 中 已经使用取代 所有的 C 标准头文件都是无后缀的 这是 的一个扩展集 提供有缓冲的文 件输入输出操作 事实上 已经被包含了 所以你不必包含所有这两个文件 如果 你想显式包含他们 那随便你 我们从文件操作类的设计开始 我会讲解如何进行 ASCII I O 操作 如果 你猜是 fstream 恭喜你答对了 但这篇文章介绍的方法 我们分别使用 ifstream 和 ofstream 来作输 入输出 如果你用过标准控制台流 cin 和 cout 那现在的事情对你来说很简单 我们现在开始讲输出部分 首先声明一个类对象 ofstream fout 这就可以了 不过你要打开一个文件的话 必须像这样调用 ofstream open fout open output txt 你也可以把文件名作为构造参数来打开一个文件 ofstream fout output txt 这是我们使用的方法 因为这样创建和打开一个文件看起来更简单 顺便说一句 如果你要打开的文 件不存在 它会为你创建一个 所以不用担心文件创建的问题 现在就输出到文件 看起来和 cout 的操作 很像 对不了解控制台输出 cout 的人 这里有个例子 int num 150 char name John Doe fout Here is a number num n fout Now here is a string name n 现在保存文件 你必须关闭文件 或者回写文件缓冲 文件关闭之后就不能再操作了 所以只有在你 不再操作这个文件的时候才调用它 它会自动保存文件 回写缓冲区会在保持文件打开的情况下保存文 件 所以只要有必要就使用它 回写看起来像另一次输出 然后调用方法关闭 像这样 fout flush fout close 现在你用文本编辑器打开文件 内容看起来是这样 Here is a number 150 Now here is a string John Doe 很简单吧 现在继续文件输入 需要一点技巧 所以先确认你已经明白了流操作 对 比 较熟悉了 因为你接下来还要用到他们 继续 二 ASCII 输入 输入和 cin 流很像 和刚刚讨论的输出流很像 但你要考虑几件事情 在我们开始复杂的内容之前 先看一个文本 12 GameDev 15 45 L This is really awesome 为了打开这个文件 你必须创建一个 in stream 对象 像这样 ifstream fin input txt 现在读入前四行 你还记得怎么用 操作符往流里插入变量和符号吧 好 在 提取 操作符 使用方法是一样的 看这个代码片段 int number float real char letter word fin number fin word fin real fin letter 也可以把这四行读取文件的代码写为更简单的一行 fin number word real letter 它是如何运作的呢 文件的每个空白之后 操作符会停止读取内容 直到遇到另一个 操作符 因为我们读取的每一行都被换行符分割开 是空白字符 操作符只把这一行的内容读入变量 这就是 这个代码也能正常工作的原因 但是 可别忘了文件的最后一行 This is really awesome 如果你想把整行读入一个 char 数组 我们没办法用 操作符 因为每个单词之间的空格 空白字 符 会中止文件的读取 为了验证 char sentence 101 fin sentence 我们想包含整个句子 This is really awesome 但是因为空白 现在它只包含了 This 很明显 肯定 有读取整行的方法 它就是 getline 这就是我们要做的 fin getline sentence 100 这是函数参数 第一个参数显然是用来接受的 char 数组 第二个参数是在遇到换行符之前 数组允许 接受的最大元素数量 现在我们得到了想要的结果 This is really awesome 你应该已经知道如何读取和写入 ASCII 文件了 但我们还不能罢休 因为二进制文件还在等着我们 三 二进制 输入输出 二进制文件会复杂一点 但还是很简单的 首先你要注意我们不再使用插入和提取操作符 译者注 操作符 你可以这么做 但它不会用二进制方式读写 你必须使用 read 和 write 方法读取 和写入二进制文件 创建一个二进制文件 看下一行 ofstream fout file dat ios binary 这会以二进制方式打开文件 而不是默认的 ASCII 模式 首先从写入文件开始 函数 write 有两个 参数 第一个是指向对象的 char 类型的指针 第二个是对象的大小 译者注 字节数 为了说明 看 例子 int number 30 fout write char 第一个参数写做 char char letter obj obj number 15 obj letter M fout write char 这样就写入了整个结构 接下来是输入 输入也很简单 因为 read 函数的参数和 write 是完全一样 的 使用方法也相同 ifstream fin file dat ios binary fin read char 我不多解释用法 因为它和 write 是完全相同的 二进制文件比 ASCII 文件简单 但有个缺点是无法 用文本编辑器编辑 接着 我解释一下 ifstream 和 ofstream 对象的其他一些方法作为结束 四 更多方法 我已经解释了 ASCII 文件和二进制文件 这里是一些没有提及的底层方法 检查文件 你已经学会了 open 和 close 方法 不过这里还有其它你可能用到的方法 方法 good 返回一个布尔值 表示文件打开是否正确 类似的 bad 返回一个布尔值表示文件打开是否错误 如果出错 就不要继续进一步的操作了 最后一个检查的方法是 fail 和 bad 有点相似 但没那么严重 读文件 方法 get 每次返回一个字符 方法 ignore int char 跳过一定数量的某个字符 但你必须传给它两个参数 第一个是需要跳过的字符 数 第二个是一个字符 当遇到的时候就会停止 例子 fin ignore 100 n 会跳过100个字符 或者不足100的时候 跳过所有之前的字符 包括 n 方法 peek 返回文件中的下一个字符 但并不实际读取它 所以如果你用 peek 查看下一个字符 用 get 在 peek 之后读取 会得到同一个字符 然后移动文件计数器 方法 putback char 输入字符 一次一个 到流中 我没有见到过它的使用 但这个函数确实存在 写文件 只有一个你可能会关注的方法 那就是 put char 它每次向输出流中写入一个字符 打开文件 当我们用这样的语法打开二进制文件 ofstream fout file dat ios binary ios binary 是你提供的打开选项的额外标志 默认的 文件以 ASCII 方式打开 不存在则创建 存在 就覆盖 这里有些额外的标志用来改变选项 ios app 添加到文件尾 ios ate 把文件标志放在末尾而非起始 ios trunc 默认 截断并覆写文件 ios nocreate 文件不存在也不创建 ios noreplace 文件存在则失败 文件状态 我用过的唯一一个状态函数是 eof 它返回是否标志已经到了文件末尾 我主要用在循环中 例如 这个代码断统计小写 e 在文件中出现的次数 ifstream fin file txt char ch int counter while fin eof ch fin get if ch e counter fin close 我从未用过这里没有提到的其他方法 还有很多方法 但是他们很少被使用 参考 C 书籍或者文 件流的帮助文档来了解其他的方法 结论 你应该已经掌握了如何使用 ASCII 文件和二进制文件 有很多方法可以帮你实现输入输出 尽管很少 有人使用他们 我知道很多人不熟悉文件 I O 操作 我希望这篇文章对你有所帮助 每个人都应该知道 文件 I O 还有很多显而易见的方法 例如包含文件 我更喜欢用流是因为他们更简单 祝所有读 了这篇文章的人好运 也许以后我还会为你们写些东西 阅读全文 2540 评论 1 复制链接 VC Studio 使用技巧使用技巧 2006 4 5 23 12 00 1 检测程序中的括号是否匹配 把光标移动到需要检测的括号 如大括号 方括号 圆括号 和尖括号 前面 键入快捷键 Ctrl 如果括号匹配正确 光标就跳到匹配的括号处 否则光标不移动 并且机箱喇叭还会发出一声 警告声 2 查看一个宏 或变量 函数 的宏定义 把光标移动到你想知道的一个宏上 就比如说最常见的 DECLARE MAP MESSAGE 上按一下 F12 或右键菜单中的 Go To Defition Of 如果没有建立 Browse files 会出现提示对话框 确定 然后 就会跳到定义那些东西的地方 3 格式化一段乱七八糟的源代码 选中那段源代码 按 ATL F8 4 在编辑状态下发现成员变量或函数不能显示 删除该项目扩展名为 ncb 文件 重新打开该项目 5 如何整理 ClassView 视图中大量的类 可以在 classview 视图中右键新建文件夹 new folder 再把具有相近性质的类拖到对应的文件夹中 使整个视图看上去清晰明了 6 定位预处理指定 在源文件中定位光标到对称的 if endif 使用 Ctrl K 7 如何添加系统中 Lib 到当前项目 在 Project Settings Link Object library modules 输入 Lib 名称 不同的 Lib 之间用空格格开 8 如何添加系统中的头文件 h 到当前项目 include 告诉编译到 VC 系统目录去找 使用 include FileName h 告诉编译在当前 目录找 9 如何在 Studio 使用汇编调试 在 WorkBench 的 Debugger 状态下按 CTRL F7 10 怎样处理 ClassZiard 找不到的系统消息 如果要在 ClassWizard 中处理 WM NCHITTEST 等系统消息 请在 ClassWizard 中 Class Info 页中将 Message filter 改为 Window 就有了 11 如何干净的删除一个类 先从 Workspace 中的 FileView 中删除对应的 h 和 cpp 文件 再关闭项目 从实际的文件夹中删除对应 的 h 和 cpp 文件与 clw 文件 12 如果让控制台应用程序支持 mfc 类库 可以在控制台应用程序中 include 来引入 mfc 库 但是控制台应用程序缺省是单线程的 mfc 是多线 程的 为解决该矛盾 在 project setting c c 选项 选择 code generation 在 use run time library 下拉框 中选择 debug multithread 13 如何汉化只有可执行代码的 exe 文件 在 nt 下利用 vc open file 以 resources 方式打开 exe 文件 直接修改资源文件 然后保存即可 附 VC 项目文件说明 opt 工程关于开发环境的参数文件 如工具条位置等信息 aps AppStudio File 资源辅助文件 二进制格式 一般不用去管他 clw ClassWizard 信息文件 实际上是 INI 文件的格式 有兴趣可以研究一下 有时候 ClassWizard 出问题 手 工修改 CLW 文件可以解决 如果此文件不存在的话 每次用 ClassWizard 的时候绘提示你是否重建 dsp DeveloperStudio Project 项目文件 文本格式 不过不熟悉的话不要手工修改 dsw DeveloperStudio Workspace 是工作区文件 其他特点和 DSP 差不多 plg 是编译信息文件 编译时的 error 和 warning 信息文件 实际上是一个 html 文件 一般用处不大 在 Tools Options 里面有个选项可以控制这个文件的生成 hpj Help Project 是生成帮助文件的工程 用 microsfot Help Compiler 可以处理 mdp Microsoft DevStudio Project 是旧版本的项目文件 如果要打开此文件的话 会提示你是否转换成新的 DSP 格式 bsc 是用于浏览项目信息的 如果用 Source Brower 的话就必须有这个文件 如果不用这个功能的话 可以在 Project Options 里面去掉 Generate Browse Info File 可以加快编译速度 map 是执行文件的映像信息纪录文件 除非对系统底层非常熟悉 这个文件一般用不着 pch Pre Compiled File 是预编译文件 可以加快编译速度 但是文件非常大 pdb Program Database 记录了程序有关的一些数据和调试信息 在调试的时候可能有用 exp 只有在编译 DLL 的时候才会生成 记录了 DLL 文件中的一些信息 一般也没什么用 ncb 无编译浏览文件 no compile browser 当自动完成功能出问题时可以删除此文件 build 后会自动生 成 阅读全文 2274 评论 0 复制链接 C 之父之父 Bjarne 谈谈 C 的未来发展的未来发展 2006 4 5 9 10 00 富有活力的语言需要不断改变和成长 C 也不例外 在本文中 Bjarne Stroustrup 提出了自己对 C 的设计和演化的看法 为了让编译器 工具和类库实现者跟上节奏 让用户吸收标准 C 所支持的编程技术 在早有预计的 沉寂了几年之后 委员会再次考虑语言扩展问题了 扩展工作组 已经建立了 它代替了 演化工作组 名称的改变 这是 Tom Plum 的建议 反映了更重要的是语言特性和标准类库工具的集成 我仍然是该工 作组的主席 我希望这可以确保 C 版本的连贯性和最终结果的一致性 相似的 委员会成员资格也显示 了大量人员和组织的连续参与 幸运的是 也出现了很多新的面孔 为委员会带来了新的影响和新的专家 意见 我们打算对语言本身的改变保持谨慎和保守 重点强调兼容性 主要的目的是把主要的努力引导到标 准类库的扩展上来 在标准类库方面 我们的目标是大胆进取 利用一切机会 对于标准类库 我希望根据类库技术报告的要素来建立它 使它成为一个用于系统编程的更广泛的平 台 例如 我希望看到用于某些领域的类库 例如目录 文件夹操作 线程和套接字 我还希望委员会同 情很多新的 C 程序员 提供类库工具支持背景不同的新手 不是新程序员和 C 的难民 例如 我希望 看到一个使用范围检查 STL 的标准方法 我对最频繁地被请求添加到标准类库中的标准 GUI 图形用户 接口 的期望值很低 但是 奇迹有时候也会发生 记得 STL 吗 对于语言本身 我希望重点强调支持泛型编程的特性 因为泛型编程是语言的使用取得最大进步的领 域 此处 我将调查两个关键部分 概念 Concepts 用于模板参数的类型系统 初始化器 Initializer 列表 初始化工具的泛化 与以往一样 建议的数量仍然远远超出了委员会能够处理和该语言能够吸收的数量 请记住 接受所 有好的建议是不可能办到的 该语言扩展以支持泛型编程的全部目标是为工具提供更大的一致性 允许我们用泛型直接表示用于解决问 题的类 我的其它优先考虑 与更好地支持泛型编程一起 是更好地支持初学者 目前的建议有一种值得注意 的倾向 即这些建议照顾了哪些提出和评估建议的专家用户 有些简单地帮助那些新手的建议经常被忽略 了 我认为这是一种潜在的致命的设计偏好 除非新手受到了充分的支持 否则只有很少人能够成为专家 此外 很多人并不希望成为专家 他们希望仍然是 偶然的 C 用户 例如使用 C 进行物理计算或控制 试验设备的物理学家只有有限的学习编程技术的时间 计算机专家可能会在编程技术方面花费很多时间 而不仅仅是期望 我们必须消除那些采用优良技术的不必要的障碍 一个非常简单的例子如下 vector vector v 在98年的 C 中 这会导致语法错误 因为 是一个单独的词汇记号 而不是封闭模板参数列表的 两个 V 正确的声明可能是 vector vector v 我把它看作是一种阻碍 我曾经建议这个问题值得解决 但是当前的规则和演化工作组用一些很好的 理由两次拒绝了我的建议 但是 这些理由都是语言技术方面的 而新手 包括其他语言的专家 没有兴 趣 不接受第一种 也是十分 明显的 v 声明浪费了用户和教师的时间 我希望 问题和其它相似的 阻 碍 不要再出现在 C 0 x 中 实际上 我与 Francis Glassborow 和其他人一起 正在试图系统地消除最频 繁发生的这类 阻碍 另一个 阻碍 是 使用默认的复制操作 构造或赋值 来复制带有用户自定义析构函数的类对象是合法的 在这种情况下 要求用户自定义的复制操作将消除大量的 与资源管理相关的麻烦错误 例如 考虑下面 这个过度简单化的字符串类 class String public String char pp sz strlen pp p new char sz 1 strcpy p pp String delete p char private int sz char p void f char x String s1 x String s2 s1 在构造 s2之后 s1 p 和 s2 p 指向相同的内存区域 而这块内存被删除了两次 可能导致灾难性的后 果 这个问题对于经验丰富的 C 程序员来说是很明显的 他们一般会提供适当的复制操作或禁止复制 但是 这个问题会严重地困扰新手 破坏其对语言的信任 禁止带有指针成员的类对象的默认复制行为可能更好 但是这会导致令人厌烦的兼容性问题 修补长 期存在的问题的难度比表面看起来要复杂很多 特别是在考虑 C 兼容性的时候 1 概念 Concepts D return first 在上面的代码中 我们对 In 和 Predicate 类型作出了很多假设 从代码中我们可以看出 不知什么缘 故 In 必须用适当的语义支持 和 并且我们必须能够把 In 对象复制为参数和返回值 类似的 我们可以看到 我们可以调用一个 Pred 其参数是从 In 返回的任何类型的 取值操作符 并给结果应 用了 操作符 这个结果可以被当作是布尔型的 但是 在代码中所有的这些都是隐含的 标准类库仔细 地记载转发迭代子 例子中的 In 和谓词 Pred 的这些需求 但是编译器是不会阅读手册的 试试下面 的错误 看你的编译器显示的错误信息 find if 1 5 3 14 错误 不完整的 但是十分高效的 以我的旧想法 让构造函数检查模板参数的假设条件 为基础的解决方 案现在已经广泛使用了 例如 template struct Forward iterator static void constraints T a a a 可以增加 T b a b a 可以复制 b a 可以废弃和复制结果 Forward iterator void p T constraints 上面的代码定义了一个类 只有当 T 是一个转发迭代子的时候 它才能编译 但是 Forward iterator 对象没有做任何实际的事务 因此编译器只能 并且的确是 对这种对象做微乎其微的优化操作 我们可 以在如下所示的定义中使用 Forward iterator template In find if In first In last Pred pred Forward iterator 检查模板参数类型 while first last return first Alex Stepanov 和 Jeremy Siek 做了很多工作来开发和普及这种技术 他们使用这种技术的一个地方是 Boost 类库 但是目前你会在大多数标准类库实现中发现约束类 在错误消息的质量方面 它们的差异是 很大的 但是约束类最多是一个不完整的解决方案 例如 在定义中进行测试 如果检查工作只能在声明中完 成 那么就会好很多 使用这种方式的时候 我们必须遵循接口的使用规则 并且可以开始考虑真正的模 板分开编译的可能性问题 因此 让我们告诉编译器我们所期望的模板参数 template In find if In first In last Pred pred 假设我们能够表示出 Forward iterator 和 Predicate 是什么 那么编译器现在可以不理会它的定义 单 独地检查 find if 调用了 这时我们所需要做的工作是为模板参数建立一个类型系统 在现代 C 环境中 这种 类型的类型 types of types 被称为 概念 concepts 我们可以通过很多途径来说明这种概念 从现在开始 把它们想作是直接受到语言支持的 拥有更好的语法的约束类 一个概念说明了某种类型必 须提供的什么工具 而不是说明它如何提供这些工具 完美的概念 例如 与数学抽 象 对于所有的类型 In In 可以被增加 销毁和复制 非常类似 如同最初的就是数学上的 对于所有的类型 T 只要给出了 find if 的这种声明 并且不是定义 之后 我们就可以编写 int x find if 1 2 Less than 7 这个调用会失败 因为 int 不支持 换句话说 这个调用在编译时会失败 因为 int 不是一个 Forward iterator 重要的是 它使得编译器容易报告用户语言中的错误 并且在编译时 调用会被首先看 到 不幸的是 知道迭代子参数是 Forward iterator 并且谓词参数是 Predicate 也不足以保证 find if 调用成 功编译 这两个参数是互相影响的 特别是谓词的参数是一个使用 pred first 解除引用的迭代子 我 们的目的是在与调用分离的情况下 完善模板的检测 同时在不查看模板定义的情况下 完善每个调用的 检查 因此概念必须有充分的表现能力 能够处理模板参数之中的这类迭代子 一种办法是用平行的参数 来表示概念 这与模板的参数化方式类似 例如 template Value type T Forward iterator In 迭代子在 T 序列中 Predicate Pred 带有 T 参数并返回一个布尔值 In find if In first In last Pred pred 在上面的代码中 我们要求 Forward iterator 必须指向类型 T 的元素 它也是 Predicate 的参数类型 通过普通参数 此处是参数 T 来表达模板参数之间必要的关系 很不幸没有强大的表现能力 导致我们 添加模板参数 并且间接地 无法直接地 表达需求 例如 上面的例子不能说明把 first 的结果作为参 数传递给 pred 一定可行 其实 它说明的是 Forward iterator 和 Predicate 共享了一个模板参数类型 为了 处理这类问题 我们正在研究直接表达模板参数之间关系的可能性 例如 template where assignable In find if In first In last Pred pred 这种方法也有自己的问题 例如它的要求 where 子句 趋向于增加模板定义本身的复杂性 并且流 行的迭代子 例如 int 并不拥有成员类型 例如 value type 概念的一种可能的表达方式是直接支持我们过去使用的约束类这种表达方式 例如 我们采用如下的 方式来定义前面例子中使用的 Forward iterator template concept Forward iterator 参数化的概念 Forward iterator a a a 可以增加 Forward iterator b a b a 可以复制 b a 可以废除和复制结果 T x a a x 可以认为结果是 T 类型的 或者 concept Forward iterator 概念没有用参数表示 Forward iterator a a a 可以增加 Forward iterator b a b a 可以复制 b a 可以废除和复制结果 参数化的概念定义可用于 find if 的第一种声明 不带参数的用于第二种 它们表现了可替换使用的 语言设计 我们在这个领域还会提供一些设计选择 但是 看看下面的情形 int x find if 1 2 Less than 7 这是不合格的 因为1和2是 int 型的 而 int 不支持 如果我们使用参数化的概念设计 它也是不合 格的 因为 int 不是一个能够与 Forward iterator匹配的参数化类型 另一方面 看下面的例子 void f vector int q2 find if p p n Less than 7 很明显 我是在报告目前正在进行的工作 但是某种形式的概念成为 C 0 x 的基石是很可能的 模 板已经成为多数有效的 和高效的 C 编程样式的要素 但是它遭受很多困扰 大量的 无用的错误消 息 缺乏基于模板参数重载模板的工具 分开编译很差 概念直接解决了所有这些问题 同时还没有基于 方法的抽象基类的主要缺陷 通过虚拟函数调用的运行时解析的性能开销 重要的是 概念不依赖于显式 声明的子类型层次 因此不需要逻辑冗余的层次关系 并且可以认为内建类型与类是平等的 现在以概念和它与其它语言中相似的构造之间可能的关系为主题的论文很广泛 Matt Austern Jaako J rvi Mich Marcus Gabriel Dos Reis Jeremy Siek Alex Stepanov 和我都活跃在这个设计问题的领域 2 泛化的初始化器 C 的一个基本的想法是 对用户定义类型的支持如同内建类型一样好 但是 看看下面的情形 double vd 1 2 2 3 3 4 4 5 5 6 vector v vd vd 5 我们可以直接使用初始化器列表来初始化该数组 然而对 vector 来说 我们做得最好 指坏处最少 的方式就是建立一个数组并用该数组来初始化 vector 如果只有少量几个初始化器值 我甚至于可能使用 下面的方式来避免明确地说明初始化器值的数量 在上面的例子中是 5 vector v v push back 1 2 v push back 2 3 v push back 3 4 v push back 4 5 v push back 5 6 我认为谁也无法适当地调用上面的任何解决方案 为了得到最容易维护的代码 并且不让内建 并且 是天生危险的 数组受到的 宠爱 比推荐的用户定义类型多 vector 我们可以编写下面的代码 vector v 1 2 2 3 3 4 4 5 5 6 或者 vector v 1 2 2 3 3 4 4 5 5 6 由于参数传递是在初始化过程中定义的 因此对于带有 vector 的函数来说 这也是可行的 void f const vector f 1 2 2 3 3 4 4 5 5 6 我相信这种初始化器的泛化会成为 C 0 x 的一部分 它将成为构造函数检查工作的一部分 因为人 们发现的很多缺陷都似乎可以通过构造函数的泛化 例如转发构造函数 有保障的编译期构造函数 继承 的构造函数 来解决 作者 陶刚编译 阅读全文 1707 评论 0 复制链接 C 之父之父 Bjarne 谈谈 C 在在2005年年 2006 4 5 9 07 00 现在我们仍然很难估计 C 程序员的数量 但在2003年 IDC 报告说有超过300万的全职 C 程序员 这个数据还是比较可信的 虽然我不能够精确地计算 但是我所拥有的所有指标都显示 C 在经过前十 年 1985 1994 的爆炸性增长之后 后十年 1995 2004 其使用人数一直在稳定地增长 我还没有经 历过其增长停止的时期 我猜想 虽然面对竞争产品的有力宣传和肆无忌惮的促销活动 它仍然稳定增长 的主要原因在于 在这个时期中 C 语言保持着稳定性 stability 在这些年头中 这种语言的实现有了 很大的改善 其类库的数量 质量和复杂程度都有所增长 同时我们对如何使用 C 的理解也进一步深入 了 但是 1995年 D就 表示从标准输入流中读取一个指定类型 即变量 x 的类型 的数据 在 C 中 对文件的操作是通过 stream 的子类 fstream file stream 来实现的 所以 要用这种方式操作文 件 就必须加入头文件 fstream h 下面就把此类的文件操作过程一一道来 一 打开文件 在 fstream 类中 有一个成员函数 open 就是用来打开文件的 其原型是 void open const char filename int mode int access 参数 filename 要打开的文件名 mode 要打开文件的方式 access 打开文件的属性 打开文件的方式在类 ios 是所有流式 I O 类的基类 中定义 常用的值如下 ios app 以追加的方式打开文件 ios ate 文件打开后定位到文件尾 ios app 就包含有此属性 ios binary 以二进制方式打开文件 缺省的方式是文本方式 两种方式的区别见前文 ios in 文件以输入方式打开 ios out 文件以输出方式打开 ios nocreate 不建立文件 所以文件不存在时打开失败 ios noreplace 不覆盖文件 所以打开文件时如果文件存在失败 ios trunc 如果文件存在 把文件长度设为0 可以用 或 把以上属性连接起来 如 ios out ios binary 打开文件的属性取值是 0 普通文件 打开访问 1 只读文件 2 隐含文件 4 系统文件 可以用 或 或者 把以上属性连接起来 如3或1 2就是以只读和隐含属性打开文件 例如 以二进制输入方式打开文件 c config sys fstream file1 file1 open c config sys ios binary ios in 0 如果 open 函数只有文件名一个参数 则是以读 写普通文件打开 即 file1 open c config sys file1 open c config sys ios in ios out 0 另外 fstream 还有和 open 一样的构造函数 对于上例 在定义的时侯就可以打开文件了 fstream file1 c config sys 特别提出的是 fstream 有两个子类 ifstream input file stream 和 ofstream outpu file stream ifstream 默认 以输入方式打开文件 而 ofstream 默认以输出方式打开文件 ifstream file2 c pdos def 以输入方式打开文件 ofstream file3 c x 123 以输出方式打开文件 所以 在实际应用中 根据需要的不同 选择不同的类来定义 如果想以输入方式打开 就用 ifstream 来 定义 如果想以输出方式打开 就用 ofstream 来定义 如果想以输入 输出方式来打开 就用 fstream 来定 义 二 关闭文件 打开的文件使用完成后一定要关闭 fstream 提供了成员函数 close 来完成此操作 如 file1 close 就把 file1相连的文件关闭 三 读写文件 读写文件分为文本文件和二进制文件的读取 对于文本文件的读取比较简单 用插入器和析取器就可以了 而对于二进制的读取就要复杂些 下要就详细的介绍这两种方式 1 文本文件的读写 文本文件的读写很简单 用插入器 从文件输入 假设 file1是以输入方式打 开 file2以输出打开 示例如下 f

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论