《Effective C++》读书笔记之item27:尽量少做转型动作

1.C++是强类型语言,一般编译器会检查出不适合的转型操作。

2.类型转换的形式:

  • 旧式转型(两种方式本质相同):
    • C风格:(T)expression。
    • 函数风格:T(expression)。
  • 新式风格(或C++风格):
    • const_cast<T>(expression):去除表达式的常量性,是C++中唯一能做此操作的转型操作符。
    • dynamic_cast<T>(expression):主要用来执行“安全向下转型”,即用来决定某对象是否归属继承体系中的某个类型。它是唯一无法由旧式语法执行的动作,也是唯一可能耗费重大运行成本的转型动作。
    • reinterpret_cast<T>(expression):试图执行低级转型(例如将一个指向整数变量的指针转换为整数),实际动作及结果可能与编译器相关,因而降低了可移植性。
    • static_cast<T>(expression):隐式转换。注意虽然可以使非const类型转换为const,但反之不能。

如果必须要转型,尽量使用新式风格,它们更容易识别,也更容易被编译器纠错。

3.如果一个类具有一个或多个单个参数的构造函数,则该类支持隐式类型转换:如果有必要,它可以在接受该参数类型的对象后自动将其转换为该类类型。

但是,除非有明显的理由想要定义隐式转换,否则,单形参的构造函数应该声明为explicit(在函数声明前加上explicit关键字,但是不要在类外的定义上再加此关键字)。这样类型转换就必须是显式调用的。

P118的例子里,使用显式类型转换也不是必须的,最好还是构造一个对象。

4.以一个基类指针指向派生类对象,如果基类不是虚基类,则会造成隐式的类型转换(P118的例子):对象从派生类转化为基类,从而造成“地址偏移”。由于各个编译器对内存的布局处理不尽相同,因而如果程序中使用了这种“布局处理”,可能会降低可移植性。

5.很多应用框架会要求派生类中的虚函数先调用基类中的同名函数,如:

class Window{
	public:
		virtual void onResize(){...}
		...
};
...
class SpecialWindow : public Window{
	public:
		virtual void onResize(){
			static_cast<Window>(*this).onResize();	//试图将“当前对象”转换为基类类型的对象并调用基类的同名函数
			...		//这里进行该函数区别于基类同名函数的特定行为
		}
	...
};


以上的调用并不是调用当前对象的函数,而是稍早转型动作所建立的“*this对象的基类部分“的暂时副本上的onResize()函数,意即:它先在“当前对象的基类成分”的副本上调用了基类的onResize()函数,然后在当前对象上执行了区别于基类函数的特定行为。因而,如果基类的onResize()函数改变成员变量的值,则它在派生类中的执行是无效的。

应当将相应的代码修改为:

class SpecialWindow : public Window{
	public:
		virtual void onResize(){
			Window::onResize();		//调用Window::onResize()作用于*this身上
			...
		}
...
};


6.dynamic_cast执行速度很慢,应避免使用。考虑这样一个情形:想在派生类对象上执行派生类的操作函数,但只有一个指向基类的指针或引用,可以采用两种方法加以避免:

(1)使用容器并在其中存储直接指向派生类对象的指针。(PS:意思可能是:原先那个基类指针干脆不用了,自己建立智能指针去。呃,怎么觉得作者有些无聊……)

(2)在基类内提供虚函数,使用多态。(PS:这是相当大路货的东西了,没想到竟然到这里才讲。)

7总之,转型总是应当避免的;当实在无法避免的时候,就把转型操作隔离在函数中,以方便维护。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值