疑问:类中的类型转换运算符与带参数函数调用运算符有何区别?
Bitmap类中特殊运算符重载解析
你看到的被标注的那些运算符,是用户定义的类型转换运算符,和你熟悉的括号调用运算符(operator())完全是两回事,下面给你拆解清楚:
基本定义
这类运算符的格式是 operator 目标类型(),作用是定义当前类的对象如何转换为指定的目标类型。代码里的几个例子:
operator T *():把Bitmap<T,N>对象转换成T*类型指针operator const T *() const:常量Bitmap<T,N>对象转换成const T*指针operator BitmapRef<T, N>():转换成BitmapRef<T,N>类型对象operator BitmapConstRef<T, N>() const:常量对象转换成BitmapConstRef<T,N>类型
触发方式(怎么调用)
1. 隐式触发(C++11之前的非explicit版本)
当上下文需要目标类型的值时,编译器会自动调用这些转换运算符,比如:
Bitmap<int> my_bmp; // 自动调用operator T*(),把my_bmp转成int* int* data_ptr = my_bmp; const Bitmap<int> const_bmp; // 自动调用operator const T*() const const int* const_data_ptr = const_bmp; // 自动调用operator BitmapRef<T,N>() BitmapRef<int> bmp_ref = my_bmp;
2. 显式触发(C++11的explicit版本)
加了explicit关键字后,不能自动隐式转换,必须用强制转换来触发:
Bitmap<int> my_bmp; // 用static_cast显式触发转换 int* data_ptr = static_cast<int*>(my_bmp);
和括号运算符的区别
你熟悉的operator()()是函数调用运算符,必须通过对象(参数)的形式主动调用;而这类转换运算符是被动触发的——当代码需要目标类型时,编译器自动(或你显式强制)把当前对象转成对应类型,不需要写括号传参。
补充:explicit的作用
C++11后给转换运算符加explicit,是为了防止意外的隐式转换导致bug。比如避免把Bitmap对象不小心当成指针传入一个接受T*的函数,减少不必要的类型转换错误。
内容的提问来源于stack exchange,提问作者Zebrafish
相关产品推荐
相关产品推荐

