C++日常笔记(4)

来源:互联网 发布:手机淘宝上的积分在哪 编辑:程序博客网 时间:2024/06/06 13:05

1.重载运算符 ->

重载箭头操作符
箭头操作符与众不同。它可能表现得像二元操作符一样:接受一个对象和一个成员名。对对象解引用以获取成员。不管外表如何,箭头操作符不接受显式形参。
这里没有第二个形参,因为 -> 的右操作数不是表达式,相反,是对应着类成员的一个标识符。没有明显可行的途径将一个标识符作为形参传递给函数,相反,由编译器处理获取成员的工作。
当这样编写时:
point->action();
由于优先级规则,它实际等价于编写:
(point->action)();
换句话说,我们想要调用的是对 point->action 求值的结果。编译器这样对该代码进行求值:
1.如果 point 是一个指针,指向具有名为 action 的成员的类对象,则编译器将代码编译为调用该对象的 action 成员。
2.否则,如果 point(注:中文版误写为action) 是定义了 operator-> 操作符的类的一个对象,则 point->action 与 point.operator->()->action 相同。即,执行 point 的 operator->(),然后使用该结果重复这三步。
3.否则,代码出错。

对重载箭头的返回值的约束
1.重载箭头操作符必须返回指向类类型的指针,或者返回定义了自己的箭头操作符的类类型对象。
2.如果返回类型是指针,则内置箭头操作符可用于该指针,编译器对该指针解引用并从结果对象获取指定成员。如果被指向的类型没有定义那个成员,则编译器产生一个错误。
3.如果返回类型是类类型的其他对象(或是这种对象的引用),则将递归应用该操作符。编译器检查返回对象所属类型是否具有成员箭头,如果有,就应用那个操作符;否则,编译器产生一个错误。这个过程继续下去,直到返回一个指向带有指定成员的的对象的指针,或者返回某些其他值,在后一种情况下,代码出错。

2.通用指针 void *
我们印象中C语言的指针都有类型,实际上也存在一种例外。这里涉及到通用指针,它可以指向任何类型的变量。
通用指针的类型用(void *)表示,因此也称为void 指针。

int n = 10, *p;void *v_p;v_p = &n;p = (int *)v_p

3.类型转换

在C中,类型转换使用类型转换运算符
e.g. (type)exp => 将exp转换为type类型

C++除了保证C风格的类型转换有效以外,还提供了四种不同的类型转换:
(1)static_cast < new_type > ( expression )

Returns a value of type new_type.

Note:static_cast may also be used to disambiguate function overloads by performing a function-to-pointer conversion to specific type, as in std::transform(s.begin(), s.end(), s.begin(), static_cast<int(*)(int)>(std::toupper));用于相关类型之间的转换,诸如:在同一个类的继承层次关系中,向上或向下转换;枚举类型与整数类型之间的转换;浮点类型与指数类型之间的转换。static_cast它能在内置的数据类型间互相转换,对于类只能在有联系的指针类型间进行转换。可以在继承体系中把指针转换来、转换去,但是不能转换成继承体系外的一种类型

(2)reinterpret_cast < new_type > ( expression )

Returns a value of type new_type.

字面理解即re-interpret,重新解析(释)的意思。故名思意,它主要用于不相关类型之间的转换,好一个英文单词在不同的上下文中,词性和词义可能完全不同。它为不同类型之间转换带来的便利,但是也伴随着风险的,如将一个十六进制整数转换为内存地址(由int-->指针类型,这两种类型完全不关联)。既然是用于不相关类型之间的转换,也就意味着编译器不会做太多的确认和承诺。reinterpret_cast方式还有一个特点就是:目标和原始值之间至少有相同的位数,我们可以将转换之后的值再转换回去,而不像其它3种类型可能会导致精度丢失。

(3)dynamic_cast < new_type > ( expression )

Returns a value of type new_type.

Note:A downcast can also be performed with static_cast, which avoids the cost of the runtime check, but it's only safe if the program can guarantee (through some other logic) that the object pointed to by expression is definitely Derived.一种运行时(run-time)检测的类型转换,因此转换可能需要较大的运行时代价,这种类型也是用C-style是无法实现的。主要用于执行类型向下转换和继承之间的转换。dynamic_cast 仅能应用于指针或者引用,不支持内置数据类型表达式dynamic_cast<T*>(a) 将a值转换为类型为T的对象指针。如果类型T不是a的某个基类型,该操作将返回一个空指针。它不仅仅像static_cast那样,检查转换前后的两个指针是否属于同一个继承树,它还要检查被指针引用的对象的实际类型,确定转换是否可行.

(4)const_cast < new_type > ( expression )

Returns a value of type new_type.

Note:const_cast makes it possible to form a reference or pointer to non-const type that is actually referring to a const object or a reference or pointer to non-volatile type that is actually referring to a volatile object. Modifying a const object through a non-const access path and referring to a volatile object through a non-volatile glvalue results in undefined behavior用于消除变量的const限定,转换之后的变量就不再具有“const”了,如果是一个const指针的话,转换之后可以改变指向而指向其它对象。

参考来源:
http://www.cnblogs.com/hammerc/p/4026243.html
http://en.cppreference.com/w/