C++88个注意点子之71~88

71. 操作符重载:

(1)不能通过连接其他符号来创建任何新操作符,如**(幂)非法

(2)不内置类型定义额外的新操作符(如不能为数组定义+)

(3)重载操作符必须具有至少一个类类型或枚举类型的操作数

(4)优先级和结合性是固定的,重载操作符使用默认实参非法

(5)操作符定义为非成员函数时,通常必须将它设置为所操作类的友元

(6)赋值操作符,取地址操作符,逗号操作符对类类型操作数有默认含义

(7)关联容器键类型应定义<操作符,顺序容器中,为了算法可用,应定义==,<操作符

(8)选择成员or 非成员实现:=,[ ], (), ->必须定义为成员复合赋值也应定义为成员,++, -- , *等一般为类成员,对称的操作符,如算术,相等,关系,位操作符,最好定义为非成员函数。


72.函数对象,定义了operator()成员函数

可用参考标准库函数对象(类模板),在C++ Prime 第452页


73. 类类型可转换为其他类型,需要定义operator 类名() const

类类型转换之后不能再跟另一个类类型转换。标准转换可放在类类型转换之前。


74. 多态

(1) 动态多态: 类继承和虚函数机制(动态绑定实现)

(2) 静态多态: 1. 非参数化多态(函数重载,运算符重载) 2. 参数化多态:泛型编程(类型作为参数)


75. 动态绑定:通过基类的引用(或指针)调用虚函数,发生动态绑定。引用(或指针)可指向基类也可指向派生类对象,用引用(或指针)调用的虚函数在运行时确定。


76. 一般基类需要定义虚析构函数,static成员函数不可为虚函数,virtual只在类内部的成员函数声明中出现,不能在类定义体外函数定义上出现。


77. 基类中的public成员可被派生类访问,但private成员不能被访问,protected成员可被派生类访问,但不能被其他用户访问。

基类只对外部提供public,而派生类则可以访问基类的protected, 但在派生类定义函数内部不能访问基类对象的protected。


78. 引用和指针的静态类型与动态类型可以不同,这是C++用以支持多态性的基石。 

对象的类型已知且不变,对象是非多态的。对象的动态类型总是与静态类型相同,这与引用和指针相反。


79. (1) 编译时确定非virtual调用

(2) 覆盖虚函数机制


80. 通过基类的引用或指针调用虚函数时,默认实参为在基类虚函数中声明的值,若通过派生类的指针或引用调用虚函数,则默认实参是在派生类的版本中声明的值。


81. 公用,私有和受保护的继承

(1) 公用继承(public基类):基public -> 派public; 基protected -> 派protected

(2) 受保护继承(protected基类):基public, protected -> 派protected

(3) 私有继承(private基类):基所有 -> 派private


82. 默认继承保护级别

class Base;

struct D1: Base -> struct D1: public Base

class D2: Base -> class D2: private Base


83. 友元关系与继承:友元关系并不能继承。基类的友元对派生类成员没有特殊访问权限。


84. 派生类-> 基类:

(1) 引用转换不同于转换对象

(2) 用派生类对象对基类对象进行初始化或赋值

(3) 派生类到基类转换的可访问性


85. 派生类构造函数:先调用基类的默认构造函数,然后再执行派生类的构造函数。

(1) 向基类构造函数传递实参:

Bulk_item(const std::string &book, ...): Item_base(book, sales_price), min_qty(), discard() {}

(2) 派生类只能使用直接基类构造函数初始化,初始化直接基类


86. 复制构造函数,赋值构造函数,析构函数一般都是先基类,再派生类的顺序进行。

(1) 对于复制构造函数,若不定义,则使用合成复制构造函数(先基类复制,再派生类部分),若派生类定义了自己的复制构造函数,该复制构造函数一般应显式使用基类复制初始化自己基类部分,不然,则运行Base默认构造函数初始化对象(会出问题的)

(2) 赋值同复制,若派生类显式定义了自己的赋值操作符,则必须对基类部分进行显式赋值。Base::operator=(rhs);

(3) 析构函数不一样,只负责撤销自己的部分,从底往上逆序撤销基类。


87. 基类的虚析构函数总是需要的,防止指针指向派生类。复制构造函数,构造函数,赋值操作符一定不能用虚函数。


88. 派生类作用域中嵌套着基类作用域,若派生类中成员名与基类相同,则屏蔽基类中成员,若在派生类中还想用基类成员,则Base::mem; 在派生类中定义与基类函数名一样的函数,则屏蔽基类中的,是屏蔽,不是重载,不管形参等怎样不同都屏蔽。

局部作用域中声明的函数不会重载全局作用域中函数。

基类作用域 {

     派生类作用域

}


89. 派生类中的重载函数,要么重定义函数,屏蔽基类,要么不定义,用基类重载函数。若想打破,则用using Base::函数名; 不用形参表。接着定义自己的函数。


90. 派生类中定义了与基类虚函数同名函数,但形参不一样,则屏蔽,若又定义了相同形参函数,则依次管用。


91. 纯虚函数,声明如下:virtual 返回类型 函数名(参数) = 0;

纯虚函数一定没有定义,纯虚函数用来规范派生类的行为,即接口。包含纯虚函数的类是抽象类,不能实例化,但可以定义该类类型的指针或引用,同时,该类的派生类中必须实现虚函数具体行为,不然报错。


92. 如果虚函数的基类实例返回类类型的引用或指针,则该虚函数的派生类实例可以返回基类实例返回的类型的派生类(或者类类型的指针或引用)。


93. 句柄类,管理类类型指针,特别对于基类和派生类问题有效。句柄类(智能指针)是存储指向动态分配(堆)对象指针的类。


最后加了几个注意点微笑,写完感觉C++的语法真的很复杂,比java复杂好多。个人感觉java取消了操作符重载是明智的,而且取消了多继承,改用接口来规范更是一大进步。下面一段时间希望来将java的多个注意点整理好搬上来,在java篇的注意点中整好与c++的语法特性相比,让大家感受一下java的编程优势。(我并不是一个java控,本人最喜欢的语言是python)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值