《好学的C++ 第2版》 第9章 一些高级编程技术

转向C++0x和OOP之前,需要掌握其他一些技巧。

C++命令行参数:

main函数须这样定义:

int main(int argc, char* argv[]){/*...*/}  //argc计数包括程序名,所以至少是1;argv[0]就是程序名。这两个参数可以任意使用,但是是只读的,可以随意显示或复制它们。程序中可以通过argc判断输入参数是否足够(例如大于1),通过argv判断各参数是否合法,合法的话存入其他变量使用;不合法的话提示输入后,存入其他变量中使用即可。MAX_PATH:系统能支持的文件路径名的最大长度。

除了#define, const也可用来声明常量。

C++支持重载(overloading,也称作复用):重复使用同一个函数名去处理不同类型的数据,使用时根据入参类型区分。重载函数的每一个版本都须有其函数声明和定义。  //it:类型名称不同但实际类型相同(例如typedef之后结构体的两种用法)是否算重载?  C及绝大多数非OOP语言不支持重载,只能通过函数名区分。为何?(!!!OOP樶核心概念之一:数据类型决定着函数或操作符的行为。相关话题是操作符重载:有些操作符(例如+ -)可以根据操作数的类型进行不同的处理,可以为自己的类型编写操作符函数。如果操作数的类型发生变化,编译器将生成不同的指令。it:其实加法作用于整数之间跟作用于整数和指针之间,明显机制不同。)重载还算不上这个核心概念的完美实现,在某些场合,类型信息可能到了编译阶段也还是不够完备,这时就需要多态编程技术大显身手了。(后续讲)

do{...}while(x)

switch(x)

{

case 1:

  ...

  break;   //控制权将转移至switch语句末尾,否则将转入下一个case语句

case 2:

  ...

...

default:

  ...

}

 多模块:可以使用1个以上的源代码模块(.cpp)。

同一个函数只能放进一个文件,不允许分割放入多个文件。

####重要规则####

1、每个函数的定义只能出现在某一个源文件里(it:编译器编译各个模块时检查是否有重复声明(?)和定义,其他文件的static函数定义不会被本文件编译检查到。)  //it: 头文件命名和放置位置有何规则?

2、每个源文件都必须有某个函数的声明(原型)才能调用该函数。C++编译器会在源文件里为每一个函数原型寻找与之对应的函数定义,如果找不到,编译器会假定该函数是在另一个模块里定义的。

如果某个函数需要被多个模块共享,最好办法是把它和其他共享函数的函数声明都集中放置到一个文件里去,即所谓头文件,然后在每个模块开头加上一条#include语句。那些声明就会自动成为每个模块的一部分。

用类似方法共享数据变量:

C/C++中,函数外定义的变量都是全局变量,可以在随后定义的任何函数里使用。变量默认是创建它的模块的“私有财产”。若想共享它们,就需要在每个文件(或每个头文件)里加上extern声明(extern关键字是告诉编译器该变量是在其他文件中声明的)(it:意思是从外部导入的变量)。extern用来说明变量在程序其他地方声明,有可能(但不必要)是在另一个模块里,但这种变量必须保证只在某一个模块里被创建了一次。

多模块对大型软件项目非常有用,有利于码农分工协作(实现自己模块功能和接口),以及对程序进行按逻辑划分,以及控制各个模块之间相互通信的程度。

在C这样的老语言里,使用彼此相对独立的模块是隔离私有符号和公用(共享)符号的唯一手段。(模块中的私有部分对外部不可见,不用担心其他模块来调用私有函数或访问私有数据)。

这种“公私分明”做法是产生封装效果的方法之一。(封装是C++类带来的好处之一。it:公私分明可以用类来实现,而非像C一样必须用多模块来实现。)

写好各个模块源码之后,就可将.cpp分别编译成.o,随后链接C++库,即可生成.exe。(IDE设置好之后可自动完成此过程)

(it:sourceInsight是否可直接编译?it:应可,但c代码是为linux编写的,若不支持跨平台,那编译基本通不过(例如文件路径格式就不对。怎样跨平台?))

异常处理:

大型程序才最有用。

其实除了语法错误和程序逻辑错误以外,还可以划分出第三类错误:异常。涵盖各种运行错误(例如0为除数、错用空指针、内存已满申请不到、算术计算溢出)。

异常处理的关键是对非正常情况作出平稳合理的处理,包括输出日志信息用于发现和定位。在大型程序里返回错误码要层层传递向上返回才能到达与用户互动的层次,这是大型程序里让人头痛的地方。(it:做好错误码的分类分层次就很重要)

try-catch异常处理:

除最古老版本外,C++如今版本都支持使用try-catch-throw关键字来处理各种异常。异常处理把程序中的出错处理集中到了一处,无论哪里发生错误,控制权都能跳到正确的位置。

try

{

...

throw exception_object; //例如throw 12;会抛出一个int类型的异常。异常可以是任何一种类型

}

catch(exception_type [arguments]) //异常类型与exception_type相匹配才会进入,[arguments]是可选的

//it:多个catch后带同一exception_type会怎样?不匹配会继续检查下一个catch块,若该异常一直不能被捕获,程序将终止运行

{

...

}

许多类型异常是系统抛出的,它们全都派生自exception类,因而以下代码可捕获所有系统抛出的异常:

...

catch (exception &e)

{

cout<< "raised:"<<e.what()<<endl;

}

 注意:

若想捕获“文件错误”类别的异常(例如 “file not found”),必须在打开文件之前先调用相关ifstream对象的exception函数:

ifstream in_file;

in_file.exceptions(ifstream::eofbit | ifstream::failbit | ifstream::badbit);

小结捡漏:

要想访问命令行参数,就要在声明main函数时给它增加argc和argv两个各个入参(it:只增加一个可否?)

argv是一个字符串指针数组。

重载函数在编译器件被区分了。(除了函数名字相同,这些函数其实毫不相关,干的活可以大相径庭)

只要有一个以上的函数或全局数据声明,都可把程序划分为多个源文件,其每一个都是一个模块。

一个函数可以调用在另一个模块中定义的函数,前提是前者所在模块必须引入后者的原型。把所有公用函数原型集中起来放到每个模块开始部分早已是码农共识。而把原型集中放到头文件里,是方便措施。(it:如何避免重复声明?it:之所以代码库搜到那么多重名函数却互不干扰,是因为实际编译时只能看到一个?)

#include "kissyou.h"

将在整个程序范围内共享的变量,需要在每一个相关模块里对之做出extern声明,同时,需保证在且仅在某一个模块里使用标准变量声明对此类变量进行定义。(it:若是部分文件共享,在其中一个文件中定义,在其他文件中用extern导入(或者在这些文件公用的头文件中extern导入)。若是大部分模块都要用,或者保证不会重名,或者暂时不用的模块将来可能要用,那就在被工程各个模块都include的头文件中放入extern声明。)

it:使用其他模块的函数要引入其原型;使用其他模块定义的变量要在本模块用extern声明。

时间: 2024-10-26 16:06:59

《好学的C++ 第2版》 第9章 一些高级编程技术的相关文章

Linux - Unix环境高级编程(第三版) 代码编译

Unix环境高级编程(第三版) 代码编译 本文地址:http://blog.csdn.net/caroline_wendy 时间:2014.10.2 1. 下载代码:http://www.apuebook.com/code3e.html 2. 安装依赖库:sudo apt-get install libbsd-dev  3. 进入下载目录make 4. 复制头文件和动态链接库 sudo cp ./include/apue.h /usr/include/ sudo cp ./lib/libapue

Java 线程第三版 第四章 Thread Notification 读书笔记

一.等待与通知 public final void wait() throws InterruptedException 等待条件的发生. public final void wait(long timeout) throws InterruptedException 等待条件的发生.如果通知没有在timeout指定的时间内发生,它还是会返回. public final void wait(long timeout, int nanos) throws InterruptedException

C++ Primer Plus 第六版 第16章 string类和标准模板库

1.string实际上是模板具体化basic_string<char> 的一个typedef,有默认参数,所以省略了初始化参数 2.size_type是一个依赖于实现的整形 string将string::npos定义为字符串的最大长度 3.string类的构造函数P656 4.对于c-风格字符串,3种输入方法:cin>>   cin.getline(),cin.get 对于string   ,2种输入方法:cin>>,getline(cin,string对象) 5.st

OS X下UNIX环境高级编程(第三版)学习日志-第一章ChapterI,编译apue包与第一个例程

1.从网络上获取代码,地址如下apue最新官方下载地址 2.解压到本地 由于最新版本是第三版(3rd Edition),apue.3e,就是我们要的源代码 3.编译源代码 编译过程中笔者并未遇到任何问题,所以建议大家也下载最新版本的代码来学习,贴一下笔者的环境信息 Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple

【转】apue《UNIX环境高级编程第三版》第一章答案详解

原文网址:http://blog.csdn.net/hubbybob1/article/details/40859835 大家好,从这周开始学习apue<UNIX环境高级编程第三版>,在此,我要感谢网易的一个工程师朋友和室友,没有他们,我不会开始真正的学习这本书,希望大家以后开始慢慢进步.废话少说,直接上课后习题了. UNIX高级编程第一章习题答案: 1.1在系统上验证,除根目录外,目录l和l l是不同的. 答:这个验证有很多方法可使用命令ls .cd.vim等,目录.指向当前目录,目录..指

Java 线程第三版 第六章 高级同步议题 读书笔记

多线程数据同步错误比较难检测,因为通常是与事件的特定发生顺序有关. 一.同步术语 Barrier(屏障) barrier是多个Thread的集合点:所有的Thread都应该到齐在这个barrier之后才能允许它们继续下去. Condition variable(条件变量) 实际上不是变量,而是与某个lock有关联的变量. Event variable(事件变量) 条件变量的另一个名称. Critical section(临界区) 临界区是synchronized方法或者block. Lock(锁

《UNIX环境高级编程(第3版)》

<UNIX环境高级编程(第3版)> 基本信息 原书名:Advanced Programming in the UNIX Environment (3rd Edition) (Addison-Wesley Professional Computing Series) 原出版社: Addison-Wesley Professional 作者: (美)W. Richard Stevens    Stephen A. Rago 译者: 戚正伟 张亚英 尤晋元 出版社:人民邮电出版社 ISBN:9787

c++ primer plus(第6版)中文版 第九章编程练习答案

首先,说明下环境: linux:fedora14: IDE:eclipse: python:python2.7 python框架:django web服务器:apache web服务器的python模块:mod_wsgi 写在前面: 之前用的windows下面的xampp,写的php后台,现在想转向linux下面的python,跟以前一样,选择apache和eclipse作为自己的开发工具. eclipse的python配置, 参见之前的博客:http://blog.csdn.net/zy416

中文版C#高级编程第8版中的翻译错误

第180页,倒数第三行. 英文原文: If you overload == and !=, you must also override the Equals() and GetHashCode() methods inherited from System.Object; 中文译文: 在重载"=="和"!="时,还必须重载(应该是:重写)从System.Object中继承的Equals()和GetHashCode()方法. 中文版C#高级编程第8版中的翻译错误,布