C++primer13,14章总结

1.  在类内部定义的函数默认为inline

2.  const成员不能改变其所操作的对象的数据成员,const必须同时出现在声明和定义中。

3.  类背后蕴含的基本思想是数据抽象和封装。

4.  如果类通过struct定义,第一个访问标号之前是公有的,如果通过class定义,第一个访问标号前是私有的。

5.  类所定义的类型名遵循任何其他成员的标准访问控制。

6.  在声明和定义处制定inline都是合法的,像其他inline一样,inline成员函数定义必须在调用该函数的每个源文件中是可见的,不在类定义体内定义的inline函数其定义通常放在有类定义的同一个头文件中(inline doubleSales_item::avg_price()const)。

7.  构造函数声明: Screen(index h, index wid);然后在类外定义:

Screen::Screen(index h, index wid): height(h), width(wid){}

8.  一个类只能被定义一次,如果多个文件中定义一个类,那么类的定义在每个文件中必须完全相同。

9.  只声明,不定义——前向声明。 定义之前,类为不完整类型,只能有限使用(定义指针,引用,作形参,返回类型)不能用来定义该类型对象。  必须先定义类,这样编译器就会预定空间(站在编译器角度)   类内定义自身类相关变量同理。

10. 类定义后加分号是必需的。

class Sales_item{ /*...*/} accum,trans; 类定义后可接一个对象定义列表。

11. const成员函数中,this是指向const类类型对象的const指针。

在普通成员函数中,this是指向类类型对象的const指针。

12. const对象只能使用const成员。

13. 仅当形参是引用或指针时,形参是否为const才有影响,编译器可以根据实参是否为const确定调用哪一个函数。

14. const成员函数也可以修改可变数据成员(mutablemutable size_t access_ctr;

15. 定义类型的成员,如Screen::index,使用作用域操作符来访问。

16. 形参表和函数体处于类作用域中。

17. 函数返回类型不一定在类作用域中。

18. 类定义是在两个阶段中处理,①首先编译成员声明②只有在所有成员出现之后才编译他们的定义。所以如下代码将先提示B()没有返回类型错误,然后提示cout错误

    #include<iostream>

    class A

    {

        A(){cout<<endl;}

        B();

    };

19. 一旦一个名字被用作类型名,该名字就不能被重复定义。

20. 构造函数不能声明为const

21. 构造函数初始化式只在构造函数的定义中而不是声明中指定。

22. 概念上讲,可以认为构造函数分两个阶段进行①初始化阶段(有些成员必须在构造函数初始化列表中进行初始化,如const,引用,没有默认构造函数的类)②普通计算阶段。.

23. 每个成员在构造函数初始化列表中只能被指定一次。②构造函数初始化列表仅指定用于初始化成员的值,并不指定这些初始化执行的次序,成员被初始化的次序就是自定义成员的次序。

24. 内置和复合类型的成员,如指针和数组,只对定义在全局作用域中的对象才初始化,当对象定义在局部作用域时,内置或复合类型的成员不进行初始化。

25. 内置成员是什么(??)

26. 只要定义了一个构造函数(及时不是默认构造函数),编译器将不合成默认构造函数。

27. 没有默认构造函数的类型,不能用来作动态分配数组的元素类型,而静态分配数组必须为每一个元素提供一个显示初始化式。

28. 使用默认构造函数定义一个对象时不要Sales_item myobj();而是Sales_item myobj;

29. 通常,除非有明显的理由想要定义隐式转换,否则,单形参构造函数应该为explicit

30. 通常,将友元声明成组的放在类定义的开始或结尾是个好主意。

31. 类外部定义static成员函数时,无须重复指定static保留字,该保留字只出现在声明处。

32. static成员函数不能被声明为const,也不能被声明为虚函数。

33. class Bar{

     static Bar mem1;    //ok

     Bar mem2;           //error

}//static数据成员类型可以是该成员所属的类类型

class Bar{

     Bar& clear(char = bkground);

     static const char bkground = #;

};//非const数据成员不能作默认实参

34. const static成员的初始化必须放在类定义体的外部。(因为static成员不是任何对象的组成部分,所以static成员函数不能被声明为const。毕竟将成员函数声明为const就是承诺不会修改该函数所属的对象。)

35. 类定义体中初始化的const static数据成员,仍必须在类的定义体外进行定义。但定义时无需再指定初始值。(const int Accouont::period;

36. 赋值操作符右操作数为类类型的版本化比较特殊,如果我们没有编写这种版本,编译器将为我们合成一个。

37. 复制构造函数,赋值操作符和析构函数总称为复制控制。

38. 复制构造函数:只有一个本类类型对象的引用(常用const修饰)作形参的构造函数。

39. 虽然一般不能复制数组,但如果一个类具有数组成员,则合成复制构造函数将复制数组。复制数组时合成复制构造函数将复制数组的每一个元素。

40. 为了防止复制,类必须显示声明其复制构造函数为private,如果要连友元和成员中的复制也禁止,就可声明private复制构造函数但不对其定义(这个就是规定。。)

41. 声明而不定义成员函数是合法的,但是使用未定义成员的任何尝试将导致链接失败。

42. 类里数组成员怎么用构造函数的初始化列表进行初始化。

43. 不定义复制构造函数和默认构造函数会严重局限类的使用,如:不能用作容器的元素(容器中储存的是副本),不能做形参等等

44. 构造函数的一个用途是自动获取资源,例如分配一个缓冲区,或打开一个文件。析构函数完成回收,作为类构造函数的补充。

45. 容器中的元素总是按逆序撤销。   三法则:复制控制往往同时需要。

46. 析构函数与复制构造函数或赋值操作符的一个重要区别是:即使写了自己的析构函数,合成析构函数仍运行。

47. 即使对象赋值给自己,赋值操作符的正确工作也非常重要,保证这个行为的通用方法是显示检查对自身的赋值。

48. 赋值操作符通常要做复制构造函数的和析构函数也要完成的工作,在这种情况下通用工作放在private实用函数中。

49. 智能指针,用户决不能删除指针,类将保证在撤销指向对象的最后一个对象时删除指针。

50. 管理指针的这些方法用的非常频繁,因此使用带指针成员类的程序员必须充分熟悉这些编程技术。

51. 值类型——string

52. 值类型的构造函数,复制构造函数,赋值操作符的写法:值类型中的指针成员时定义对象时就该分配好的,所以赋值函数中无需重新分配指针指向的空间。

53. newdelete是操作符,可重载

54. 内置类型的操作符其含义不能改变,也不能给内置类型定义额外新的操作符。

55. 重载操作符必须具有至少一个类类型或枚举类型成员。

56. 操作符的优先级,结合性或操作数目不能改变。

57. 除了函数调用操作符operator()之外,重载操作符时使用默认实参是非法的。

58. 不再具备短路求值特性,因此重载&&、||或逗号操作符不是一种好的做法。

59. 一般将算数和关系操作符定义为非成员函数。而将赋值操作符定义为类的成员。

60. 复合赋值返回对左操作数的引用。

61. item1 + item2 等价于 operator+(item1, item2)

62. 重载逗号,取地址,逻辑与,逻辑或等操作符通常不是好做法,这些操作符具有有用的内置含义,如果我们定义了自己的版本,就不能再使用这些内置含义。

63. 当一个重载操作符的含义不明显时,给操作取一个名字更好。对于很少用的操作,使用命名函数通常也比操作符更好,如果不是普通操作,没有必要为简洁而使用操作符。

64. 一般而言,输出操作符应对输出对象的内容进行最小限度的格式化,它们不应该输出换行符。

65. 更重要但通常重视不够的是,输入操作符必须处理错误和文件结束的可能性。

66. 设计输入操作符时,如果可能要确定错误恢复措施,这很重要。

67. //构造函数定义为private的话,外部是不能访问的。但是友元和自身成员函数是可以访问的。

68. 赋值操作符必须定义为成员函数。

69. 下标操作符必须为成员函数,一般需要两个版本,一个为非const成员并返回引用,另一个为const成员并返回const引用。

70. 箭头操作符必须定义为类成员函数,解引用操作符不要求定义为成员函数,但将它作为成员一般也是正确的。

71. 重载箭头操作符必须返回指向类类型的指针,或定义了自己箭头操作符的对象

point->action 等价于 point operator->()->action

72. C++不要求自增操作符或自减操作符一定作为类的成员,但是因为这些操作符改变操作对象的状态,所以更倾向于将它们作为成员。

73. 后缀式操作符函数接受一个额外的int形参,,使用后缀操作符时,编译器提供0作为这个形参的实参(试了一下,显示用这个形参(obj++(1))会编译错误,不管是前后缀)(当然如果用operator++那就正常函数调用)。

74. 后缀操作符返回 值 而不是 引用。

75. 定义了调用操作符的类,其对象常称为函数对象,即他们是行为类似函数的对象。

76. //通过将GT6定义为带函数调用成员的类,可以获得所需的灵活性。

for(int i = 1; i != 11; i++)

{

     cout <<count_if(words.begin(), words.end(), GT_cls(i))

         << " words " << i

         << " characters or longer " << endl;

}

77.  sort(svec.begin(),svec.end(), greater<string>());//标准库定义的函数对象

78.  count_if(vec.begin(), vec.end(),bind2nd(less_equal<int>(), 10));

79. count_if(vec.begin(),vec.end(), not1(bind2nd(less_equal<int>(),10)));

80. 标准库定义了一组算数,关系与逻辑函数对象类。标准库还定义了一组函数适配器,是我们能够特化或者扩展标准库所定义的以及自定义的函数对象类。这些标准库卡函数对象类型是在functional头文件中定义的。

81. 函数适配器用于特化和扩展一元和二元函数对象。①绑定器:是一种函数适配器,它通过将一个操作数绑定到给定值而将二元函数对象转换为一元函数对象。②求反器:是一种函数适配器,它将为此函数对象的真值求反。

82. bind1st, bind2nd, not1, not2,

83. 转换操作符:是一种特殊的类成员函数。转换操作符在类定义体内声明,在保留字operator之后跟着转换的目标类型 operator int() const;

84. 一般而言,不允许转换为数组或函数类型。转换为指针类型(数据或函数指针)以及引用类型是可以的。

85. 转换函数必须是成员函数,不能指定返回类型,并且形参表必须为空。

86. 虽然转换函数不能指定返回类型,但是每个转换函数必须显示返回一个指定类型的值。

87. 转换函数一般不应该改变被转换的对象。因此,转换操作符通常应定义为const成员。

88. 类类型转换之后不能再跟另一个类类型转换。

89. 一般而言,给出一个类与两个内置类型之间的转换是不好的做法。

90. 当两个类定义了互相转换时,很可能存在二义性。

91. 避免二义性最好的方法是,保证最多只有一种途径将一个类型转换为另一类型。做到这一点,最好的办法是限制转换操作符的数目,尤其是,到一种内置类型应该只有一个转换。

92. 在调用重载函数时,需要使用构造函数或强制类型转换来转换实参,这是设计拙劣的表现。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值