(整理自Effctive C++,转载请注明。整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/

下面是每一位C++程序员都应该了解的C++词汇。

1  C++中 声明和定义 的区别

注意:关于声明和定义的区别,我查了一些资料,和本书也有不一致的地方。暂且按照本书,欢迎指正!。

所谓声明式(declaration)是指定某个东西的名称和类型,但略去细节。就是通知编译器这有一个与这个名字相关的东西,并且它是这个类型的。例如:

   1: extern int x ;    //对象(object)声明

   2: std::size_t numDigits(int number) ; //函数声明

   3: class Wjdget ;  //类的声明

   4: template<typename T>

   5: class GraphNode ;   //模版声明

注意:作者将内置类型的变量和用户自定义类型的的变量都视为对象。
 
    所谓定义式(definition)的任务是提供编译器一些声明式所遗漏的细节。对于对象而言定义是编译器为对象分配内存的地点。对函数或函数模版而言, 定义式提供了代码的本体。对于类或者类模版而言,定义式列出它们的成员。例如:
   1: int x ; //对象的定义

   2:  

   3: std::size_t numDigits(int number)    //函数的定义式

   4: {                                    //次函数返回的是整数数字的位数

   5:     std::size_t digitsSoFar = 1 ;

   6:  

   7:     while((number/=10)!=0) ++digitsSoFar ;

   8:     return digitsSoFar ;

   9: }

  10:  

  11: class Widget        //class的定义式

  12: {

  13: public:

  14:     Widget() ;

  15:     ~Widget() ;

  16:     ...

  17: };

  18:  

  19: template<typename T> //模版的定义式

  20: class GraphNode

  21: {

  22: public:

  23:     GraphNode() ;

  24:     ~GraphNode() ;

  25:     ...

  26: };

 

2  关于构造函数

2.1 默认构造函数和explicit声明

对用户自定义的类型的对象而言,初始化由构造函数执行。default构造函数是一个可被调用而不带任何实参者。这样的构造函数要不没有参数,要不就是每个参数都有缺省值。构造函数被声明为explicit,这可以阻止它们被用来执行隐式的类型转换(implicit type conversions),但仍可被用来就行显示的类型转换(explicit type conversions) :

   1: class B

   2: {

   3: public:

   4:     explicit B(int x = 0 , bool b = true ); //default构造函数

   5: };

   6:  

   7: void doSomething (B bObject) ; //函数,接受一个B类型的对象

   8:  

   9: B bObject1 ;  //一个类型为B的对象

  10: doSomething (bObject1) ; //没问题,传递一个B类对象

  11:  

  12: B bObject2(28) ;  //没问题,根据int 28建立一个B类对象(bool参数缺省为true)

  13:  

  14: doSomething (28) ; //错误!doSomething应该接受一个B类对象,而不是int,而int和B之间没有隐式的类型转换

  15:  

  16: doSomething (B(28)) ; //没问题,使用B的构造函数将int显示转换为一个B类对象,从而调用合法

被声明为explicit的构造函数比no-explicit更受欢迎,因为它们禁止编译器执行非预期的类型转换。除非有非常明确的理由允许构造函数被用于隐式类型转换,否则应声明为explicit。

2.2 copy构造函数和copy赋值操作符

copy构造函数被用来“以同型对象初始化自我对象”,copy赋值操作符被用来“从另一个同型对象拷贝其值到自我对象”。例如:

   1: class Widget

   2: {

   3: public:

   4:     Widget();                //default构造函数

   5:     Widget(const Widget& rhs );            //copy构造函数

   6:     Widget& operator= (const Widget& rhs);        //copy赋值操作符

   7:     ...

   8: };

   9:  

  10: Widget w1 ;  //调用default构造函数

  11: Widget w2(w1);  //调用copy构造函数

  12: w1 = w2 ;   //调用copy赋值操作符

  13: Widget w3 = w2 ;//调用copy构造函数

copy构造函数和copy赋值操作符很容易区别:如果一个新对象被定义,一定会有个构造函数被调用,不可能调用赋值操作。如果没有新对象被定义,就没有构造函数被调用,那么当然就是赋值操作被调用。

3 不明确行为

由于各种因素,有些C++的行为没有定义:你无法稳定预估运行期会发生什么事。看如下代码:

   1: int* a ;

   2: *a = 12 ;

这个声明创建了一个名叫a的指针变量,后面那条语句把12存储在a所指向的内存位置。我们在声明指针时没有给它初始化,所以我们无法预测12这个值会存储在什么地方。所以如果程序执行这个赋值操作,会发生什么情况呢?如果你运气好,a的初始值会是个非法地址,这样的赋值语句就会出错,从而终止程序;一个更为严重的情况是:这个指针偶尔可能包含了一个合法的地址。那么那个位置的值就会被修改,虽然你并无意去修改它。像这种类型的错误非常难以捕捉,因为引发错误的代码可能与原先用于操作那个值的代码完全不相关。所以,在对指针进行间接访问之前,必须对其进行初始化。同样的对NULL指针解引用,对数组越界操作,都会引发不明确行为。

Effective C++_笔记_条款00_基本术语的更多相关文章

  1. Effective C++_笔记_条款12_复制对象时勿忘其每一个成分

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 编译器会在必要时候为我们的classes创建copying函数, ...

  2. Effective C++_笔记_条款02_尽量以const、enum、inline替换#define

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 这个条款或许改为“宁可以编译器替换预处理器”比较好,因为或许#d ...

  3. Effective C++_笔记_条款01_视C++为一个语言联邦

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) C++的各种能力和特性使它成为一个无可匹敌的工具,但也可能引发某 ...

  4. Effective C++阅读笔记_条款2:尽量以const,enum,inline替换#define

    1.#define缺点1 #define NUM 1.2 记号NUM可能没有进入记号表,在调试或者错误信息中,无法知道1.2的含义. 改善:通过const int NUM = 1.2; 2.#dein ...

  5. Effective C++_笔记_条款11_在operator=中处理“自我赋值”

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为什么会出现自我赋值呢?不明显的自我赋值,是“别名”带来的结果: ...

  6. Effective C++_笔记_条款09_绝不在构造和析构过程中调用virtual函数

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为方便采用书上的例子,先提出问题,在说解决方案. 1 问题 1: ...

  7. Effective C++_笔记_条款08_别让异常逃离析构函数

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) C++并不禁止析构函数吐出异常,但它不鼓励你这样做.考虑如下代码 ...

  8. Effective C++_笔记_条款07_为多态基类声明virtual析构函数

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 这个规则只适用于polymorphic(带多态性质的)base ...

  9. Effective C++_笔记_条款06_若不想使用编译器自动生成的函数,就该明确拒绝

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 通常如果你不希望class支持某一特定机能,只要不声明对应函数就 ...

随机推荐

  1. Codeforces Round #316 (Div. 2B) 570B Simple Game 贪心

    题目:Click here #include <bits/stdc++.h> using namespace std; typedef long long ll; const int IN ...

  2. 版本管理神器git上手

    由于以前折腾过svn,虽然最终没有用成功,但是也算有经验,git入门还是比较简单的. 在新目录下建立初始化版本库  : git init git add file git add file2 git ...

  3. emoji表情键盘 回退删除方法

  4. 多玩YY聊天记录解析全过程

    再来一发,现在开始! 下载安装YY,观察YY目录,很明显的发现了sqlite3.dll,这个数据库很多很多很多软件都在用,简单小巧且开源.删除sqlite3.dll 进入YY,历史记录不能正常显示,基 ...

  5. poj1920 Towers of Hanoi

    关于汉诺塔的递归,记住一个结论是,转移n个盘子至少需要2^n-1步 #include<iostream> #include<cstdio> #include<cmath& ...

  6. Bmp 解析 (2013-09-09 19:30:41)

    bmp 图片结构 位图格式(bmp)是显示图片的基本格式,其文件扩展名为*.BMP. 在Windows下,任何各式的图片文件(包括视频播放)都要转化为位图才能显示出来,其他各种格式的图片文件是在位图格 ...

  7. Vi/VIM键盘图, Vi/vim学习图

    Vi/vim学习图 引用: Vi键盘图片可视化教程 http://www.cnblogs.com/me115/archive/2010/11/16/1878295.html 网上的文章易流失.感谢分享 ...

  8. 【转载】django在eclipse环境下建web网站

    一.创建一个项目如果这是你第一次使用Django,那么你必须进行一些初始设置.也就是通过自动生成代码来建立一个Django项目--一个Django项目的设置集,包含了数据库配置.Django详细选项设 ...

  9. Swift - .plist文件数据的读取和存储

    每次在Xcode中新建一个iOS项目后,都会自己产生一个.plist文件,里面记录项目的一些配置信息.我们也可以自己创建.plist文件来进行数据的存储和读取. .plist文件其实就是一个XML格式 ...

  10. MSSQL - SqlDataReader

    DataReader对象: ·DataReader对象是一个读取行的只读流的方式,绑定数据时比使用数据集方式性能要高,因为他是只读的,所以如果要对数据库中的数据进行修改就需要借助 将所做的修改保存到数 ...