备忘录 C/C++

来源:互联网 发布:显示经纬度的软件 编辑:程序博客网 时间:2024/06/05 02:12

目录:
1、成员函数的重载、覆盖与隐藏?
2、用户自定义类型转换的方法?
3、声明的定义的区别?
4、类模板的使用方法总结? 
 5、const的修饰问题?


       --摘自《高质量C++/C 编程指南》

成员函数被“重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。

覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。

隐藏规则的特征是:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual
关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual
关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

用户自定义类型转换的方法?

    首先应该明白什么是“隐式转换”和“强制转换”?

   前者是指:在算数运算和关系运算中如果参与运算的操作数类型不一致,则系统自动对数据进行转换,转换的原则是将低类型数据转换为高类型数据。这种转换过程中数据的精度没有损失,但是在赋值运算中,则要求一例将右值类型转换为左值类型,这存在精度损失。

  后者是指:强制转换往往是显式的转换,这种转换是暂时性的,一次性的。

  在用户定义的转换中,如果要把一个类对象隐式转换成其他类型的对象,使用转换函数,形式如下: 

   Operator type();

 这里的type 可用内置类型类类型或typedef 名取代,但是不允许type 表示数组或函数。

类型转换函数必须是成员函数它的声明不能指定返回类型和参数表.

         凡是只有一个参数的类的构造函数,每一个函数都定义了一个隐式转换。可以使用explicit来告诉编译器不要使用那个显式构造函数来执行隐式类型转换。

   用户定义的转换是由转换函数或构造函数执行的。正如前面已经看到的在转换函

数执行转换之后接着可以有一个“标准转换”把转换函数的结果转换成最终的目标类型。类似地,构造函数执行转换之前也可以有一个“标准转换”把要被转换的值变成构造函数参数的类型。这里“标准转换”指系统内置的转换。

声明和定义的区别?

 

声明:一种把一个名称引入或者重新引入到某个C++作用域的构造。 
    定义:它也是一种声明,但该声明必须给出被声明实体的细节。 对于变量而言,这里的细节是指:为被声明实体保留存储空间。对于class类型和函数定义而言,指的是包含有一队花括号内容的声明。 对于外部变量而言,指的是前面没有关键字extern或者在声明时就进行初始化。  

变量的声明有两种情况: 
    一种是需要建立存储空间的。例如:int a 在声明的时候就已经建立了存储空间。 
    另一种是不需要建立存储空间的 例如:extern int a 其中 变量a是在别的文件中定义的.前者是"定义性声明(defining declaration)"或者称为"定义(definition)",而后者是"引用性声明 (referncing declaration)" 从广义的角度来讲 声明中包含着定义,但是并非所有的声明都是定义,例如:int a 它既是声明,同时又是定义。然而对于 extern a 来讲 它只是声明不是定义。一般的情况下我们常常这样叙述,把建立空间的声明称之为"定义",而把不需要建立存储空间称之为"声明"。很明显我们在这里指的生命是范围比较窄的,也就是说非定义性质的声明.    --摘自erictb的blog 

    编译器总是对每一个cpp文件分别进行编译,这就是为什么debug文件夹下来总是存在多个obj文件。编译器必须知道被编译的cpp文件内的所有“类型信息”,所以我们总是经常include别的头文件,然后链接器会正确链接obj文件。
    C++里的函数声明“隐式”表达该函数会在别个地方定义。如果在函数前面加一个extern的话,就变成显式声明了。在变量前面使用extern的话,只是声明一个对象,而不分配内存。详细参看《C+primer331页。
    另外,extern “c”加在函数前面表示函数是用C语言写的函数, 不过他只能够压制nonmember function的“mangling”效果。同时,变量前面的extern “c”也只是表示声明。

类模板的使用方法总结?

模板参数可以是一个模板类型参数也可以是一个模板非类型参数(它代表了一个常量表达式)。

显式实例声明:

在定义了模版类后,可以用template class Queue<int>显式实例声明。也可以使用template特化整个模版类或者某一个特化函数。甚至可以特化模版参数的某一个,template <int hi, int wid>class Screen

{}改写成template <int hi>class Screen<hi, 80>{}

模板有两种编译模式:“包含编译模式”和“分离编译模式”。前者要求将模板的定义放在一个头文件中,也提供一个cpp文件来包含这个头文件,这样编译器才能编译模版定义。

const的修饰问题?
类似const int* & rp、const int *、int * const这样的语句,const在其中到底修饰谁?

根据C++98标准8.3.2对引用的定义:
对于声明:
    T D;
  如果D具有如下形式:
    & D1         //注意,&与D1之间不能有任何cv修饰符
 那么标识符D1的类型为“reference to T”。
 对于“const int* & rp”套用上面的格式,则:
         T                      D;
   const int*              &rp;
这样,D就具有了&D1的形式,其中D1为rp。而T,则是const int*。

const int * & 表示:“a non-const reference to T where T is a pointer to 'const int' ”。
const int *表示:“pointer to 'const int'”。
int * const表示:“const pointer to int”。

对于引用,还有一个很重要的原则:
const 常量引用(reference to const T)可以用不同类型的对象初始化,只要能从一种类型转换到另一种类型即可,也可以是不可寻址的值如文字常量。
包括两种常见的方式:

double dval = 3.14159; const int &ir = 1024;
const int ival = 1024;   const int * const &pi_ref = &ival; //需要常量指针

0 0
原创粉丝点击