Thorny_Devil 发表于 2015-3-14 13:00

C++知识点(持续更新...)

本帖最后由 Thorny_Devil 于 2015-4-7 20:52 编辑

最近刚开始看老谭的《C++面向对象程序设计》(第二版),做个笔记。

----------------------------------------------------------------------------------------------------


*如果要指定输出所占的列数,可以用控制符 setw 进行设置,需要在程序的开头包含头文件 iomanip 。
例:
    cout << setw(6) << 3.45 << endl;

*函数模板:建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表,这个通用函数就称为函数模板。
一般形式:
    template<typename T>
    通用函数定义

    template<class T>
    通用函数定义

使用注意:只适用于函数的参数个数相同而类型不同,且函数体相同的的情况,如果参数个数不同,则不能使用函数模板。


*有默认参数的函数
注意:一个函数不能既作为重载函数,又作为有默认参数的函数。因为当调用函数时,如果少写一个参数,系统无法判定是利用重载函
      数还是利用默认参数的函数,会出现二义性,系统无法执行。

*字符串变量: 必须先定义后使用,定义字符串变量要用类名 string 。定义时不需要指定长度,它的长度随其中的字符串长度而改变。
   字符串常量以‘\0‘作为结束符,但将字符串常量存放到字符串变量中时,只存放字符串本身而不包括 '\0' 。

*用 struct 声明的类和用 class 声明的类的区别:
    用 struct 声明的类,如果对其成员不作 private 或 public 的声明,系统将其默认定为 public (公用的)。
    用 class 声明的类,如果对其成员不作 private 或 public 的声明,系统将其默认定为 private (私有的)。

**类是一种抽象的数据类型,并不是一个实体,所以并不占用存储空间。
--*不论成员函数在类内定义还是在类外定义,成员函数的代码段的存储方式是相同的,都不占用对象的存储空间。
|*不论是否用 inline 声明,成员函数的代码段都不占用对象的存储空间。
--* inline 函数只影响程序的执行效率,而与成员函数是否占用对象的存储空间无关。
**

*构造函数的名字必须与类名同名,而不能任意命名。它不具有任何类型,不返回任何值,它的作用只是对对象进行初始化。
*每建立一个对象,就调用一次构造函数。

* 定义指向公用成员函数的指针变量的一般形式:
    数据类型名(类名::*指针变量名)(参数表列);

*指针变量指向一个公用成员函数的一般形式:
    指针变量名 = &类名::成员函数名;

*带有参数初始化表的构造函数的一般形式如下:
类名::构造函数名([参数表])[:成员初始化表]
{
[构造函数体]
}

*构造函数不能被用户显式调用。
*在一个类中可以包含多个构造函数,但是对于每一个对象来说,建立对象时只执行其中一个构造函数,并非每个构造函数都被执行。

*析构函数的作用并不是删除对象,而是在撤销对象占用的内存之前完成一次清理工作,使这部分内存可以被程序分配给新对象使用。
*析构函数不返回任何值,没有函数类型,也没有参数类型
*一个类可以有多个构造函数,但是只能有一个析构函数。
*调用构造函数和析构函数的顺序简记为:先构造的后析构,后构造的先析构。

********对象指针
*定义指向类对象的指针变量的一般形式:
   类名 *对象指针名;

*对象有地址,存放对象的起始地址的指针变量就是指向对象的指针变量。
*对象中的成员也有地址,存放对象成员地址的指针变量就是指向对象成员的指针变量。

*定义指向对象数据成员的指针变量的一般形式:
    数据类型名 *指针变量名;

*定义指向对象成员函数的指针变量的方法和定义指向普通函数的指针变量方法有所不同:
----定义指向普通函数的指针变量的一般形式:
    类型名 (*指针变量名) (参数表列);
----定义指向公用成员函数的一般形式:
    数据类型名 (类名:: *指针变量名) (参数表列)

----使指针变量指向一个公用成员函数的一般形式:
    指针变量名 = &类名 :: 成员函数名;


********常对象
----定义常对象的一般形式:
    类名 const 对象名[(实参表)];
也可以把const写在最左边:
    const 类名 对象名[(实参表)];
二者是等价的。

*常对象中的某个数据成员的值通常不能改变,但由于实际编程需要,对此做了特殊的处理,对该数据成员声明为mutable,
    如:mutable int count;

*只能通过构造函数的参数初始化表对场数据成员进行初始化,任何其他函数都不能对场数据成员赋值。
例:
    const int hour;
   非法:
    Time::Time(int h)
    { hour = h; }
   合法:
    Time::Time(int h):hour(h){}

*声明常成员函数的一般形式:
    类型名 函数名(参数表) const

**数据成员的引用

|         数据成员               |    非const的普通成员函数      |   const成员函数         |
-------------------------------------------------------------------------------------
| 非const的普通函数成员|   可以引用,也可以改变值      |   可以引用,但不可以改变值|
-------------------------------------------------------------------------------------
|          const数据成员       |可以引用,但不可以改变值    |    可以引用,但不可以改变值 |
-------------------------------------------------------------------------------------
|            const对象         |                     不允许                      |   可以引用,但不可以改变值|
-------------------------------------------------------------------------------------

*定义指向对象的常指针变量的一般形式:
    类名 * const 指针变量名;

*定义指向常变量的指针变量的一般形式:
    const 类型名 * 指针变量名;

**如果一个变量已被声明为常变量,只能用指向常变量的指针指向它。



********用指针作形参时形参与实参的对应关系

   |                      形参            |            实参             |合法否|改变指针所指向的变量的值    |
    ------------------------------------------------------------------------------------
   | 指向const型变量的指针   | 非const变量的地址 |   合法   |         可以               |
    ------------------------------------------------------------------------------------
   | 指向const型变量的指针   |const变量的地址   |   非法   |          /                  |
    ------------------------------------------------------------------------------------
   | 非指向const型变量的指针 |const变量的地址   |   合法   |      不可以         |
    ------------------------------------------------------------------------------------
   | 非指向const型变量的指针 | 非const变量的地址 |   合法   |      不可以         |
    ------------------------------------------------------------------------------------


*静态数据成员可以初始化,但只能在雷利外进行初始化,一般形式:
    数据类型 类名::静态数据成员名 = 初值;


重载运算符的函数一般格式:
函数类型 operator 运算符名称(形参表)
{
对运算符的重载处理
}

重载运算符的部分规则:
1> C++不允许用户自己定义新的运算符,只能对已有的C++运算符进行重载。
2> 重载不能改变运算符运算对象(即操作数)的个数。例:关系运算符”>” 和 “<” 是双目运算符,重载后仍然是双目运算符。
3> 重载不能改变运算符的优先级别。
4> 重载不能改变运算符的结合性。
5> 重载运算符的函数不能有默认的参数,否则就改变了运算符参数的个数,与2> 点矛盾。
6> 重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数应有一个是类对象(或类对象的引用)。
7> 用于类对象的运算符一般必须重载,但有两个例外,运算符“ = ” 和 “ & ”不必用户重载。

将双目运算符重载为友元函数时,注意:由于友元函数不是该类的成员函数,因此在函数的形参表列中必须有两个参数,不能省略。

C++提供显示类型转换,形式为:
类型名 (数据)
例:int (89.5) ,作用是将89.5转换为整型数89。

几种常见的构造函数:
1> 默认构造函数。以Complex 为例,函数原型的形式为:
Complex();                 //没有参数
2> 用于初始化的构造函数。函数原型的形式为:
Complex(doubler,doublei);                //形参表列中一般有两个以上参数
3> 用于复制对象的复制构造函数。函数原型的形式为:
Complex(Complex &c);                 //形参时本类对象的引用
4> 转换构造函数。
转换构造函数只有一个形参,例:
Complex (doubler) {real = r ;imag = 0;}
其作用是将double型的参数r 转换成Complex类的对象。
      注意:转换构造函数只能有一个参数,如果有多个参数,就不是构造函数。

使用转换构造函数将一个指定的数据转换为类对象的方法:
1> 先声明一个类;
2> 在这个类中定义一个只有一个参数的构造函数,参数的类型是需要转换的类型,在函数体指定转换的方法;
3> 在该类的作用域内可以用以下形式进行类型转换:
类名 (指定类型的数据)
就可以将指定类型的数据转换为此类的对象。
-----------------------------------------------------------------------------------------
类型转换函数,作用是将一个类的对象转换成另一类型的数据。
一般形式为:
operator 类型名()
{
实现转换的语句
}
例:
Complex是一个已经声明的类,real是Complex类中的数据成员,在Complex类中这样定义类型转换函数:
operator double ()
{
returnreal;
}
分析:函数返回 double 型变量real的值。它的作用是将一个Complex类对象转换为一个double型数据,其值是Complex类中的数据成员real的值。

注意:1> 在函数名前面不能指定函数类型,函数没有参数,其返回值的类型是由函数名中指定的类型名来确定的。
2.> 类型转换函数只能作为成员函数,因为转换的主体是本类的对象。不能作为友元函数或普通函数。


smartway 发表于 2015-3-14 13:18

setw对输出一些类似表格形式的数据还是挺有用的。

Flyfire 发表于 2015-3-14 13:46

setw这个函数真还没有用过,现在写MFC的时候比较多,领教了楼主的功底,赞赞赞

muyedongfeng 发表于 2015-3-14 13:55

学习下.....

lai0301 发表于 2015-3-14 17:44

学习下,那个setw函数真没用过哈。。。。。。。。。。。。。。

Thorny_Devil 发表于 2015-3-15 13:18

smartway 发表于 2015-3-14 13:18
setw对输出一些类似表格形式的数据还是挺有用的。

嗯,刚开始学,还不知道

Thorny_Devil 发表于 2015-3-15 13:21

Flyfire 发表于 2015-3-14 13:46
setw这个函数真还没有用过,现在写MFC的时候比较多,领教了楼主的功底,赞赞赞

刚开始学,,有写得不对的地方,望指教

SstudentT 发表于 2015-3-16 13:15

厉害,收藏了!楼主好样的!
页: [1]
查看完整版本: C++知识点(持续更新...)