C++库研究笔记——操作符重载实现类型转换&这样做的意义
来源:互联网 发布:r11 邮箱软件 编辑:程序博客网 时间:2024/05/17 08:30
目标:
已知这个接口:
std::vector<double> add_vec(double *d1, double *d2){.....return result;}
我们自定义了这个类:
class array{int size_;double *data_;....};
要求实现:
array v1(10), v2(10);add_vec(v1, v2);
留意到,当array 类型传入add_vec时,会遇到(double*) 类型的“试探性”强制转换, 所以,我们只要做一个从array到,(double*)的类型转换即可。
这样做的好处:
- 1.有了类型转换,我们不需要再写这样一个多态函数实现array 与array的相加
std::vector<double> add_vec(array d1, array d2){.....return result;}
- 2.以下的接口:
std::vector<double> add_vec(double* d1, double* d2)
可能重写起来非常麻烦,甚至add_vec(double*, double*) 是别人封装好的,我们看不到源代码,此时更谈不上重写实现方法及测试代码:(直接在这个代码上增加,所以代码有些乱)
C++类型转换操作符(type conversion operator)
#include <iostream> class D { public: D(double d) : d_(d) { data_=new double[10]; for(int i=0; i<10; i++) data_[i]=d; } ~D() { delete []data_; } /* “(int)D”类型转换 */ operator int() const { std::cout << "(int)d called!" << std::endl; return static_cast<int>(d_); } // for: double me= *d1; //ok double& operator*(void) { return *data_; } // for: double *me2= (double*)d1; operator double*(void){ return data_; } private: double d_; double *data_;}; int add(int a, int b) { return a + b;}#include <vector>std::vector<double> add_vec(double* d1, double* d2){ std::vector<double> r(10); for(int i=0; i<10; i++){ r[i]=d1[i]+d2[i]; } return r;} int main() { D d1 = 1.1; D d2 = 2.2; std::cout << add(d1, d2) << std::endl; double me= *d1; //ok std::cout<<"me:"<<me<<std::endl; double *me2= (double*)d1; // ok std::vector<double> r; r=add_vec(d1, d2); for(int i=0; i<r.size(); i++){ std::cout<<r[i]<<" "<<std::endl; } //std::cout << add_vec(d1, d2) << std::endl; return 0;}
输出:
(int)d called!
(int)d called!
3
me:1.1
3.3
3.3
3.3
3.3
3.3
3.3
3.3
3.3
3.3
3.3
补充:
注意到:
double me= *d1; double *me= (double*)d1;
第二个的意义为把 D类型当成一个指针, 然后把把指针(即地址)赋值给me第一个意义为:把D类型先假设指针,然后把指针指向的值转给me
二者等价,所以,可删除其中一个冗余定义,经过测试,代码仍能正常运行
// for: double *me2= (double*)d1; operator double*(void){ return data_; }
但是如果:
// for: double me= *d1; //ok double& operator*(void) { return *data_; }
则会报错:
Press ENTER or type command to continue
main.cpp: In function ‘int main()’:
main.cpp:62:27: error: invalid cast from type ‘D’ to type ‘double*’
main.cpp:63:18: error: invalid conversion from ‘int’ to ‘double*’ [-fpermissive]
main.cpp:69:21: error: invalid conversion from ‘int’ to ‘double*’ [-fpermissive]
main.cpp:44:21: error: initializing argument 1 of ‘std::vector<double> add_vec(double*, double*)’ [-fpermissive]
main.cpp:69:21: error: invalid conversion from ‘int’ to ‘double*’ [-fpermissive]
main.cpp:44:21: error: initializing argument 2 of ‘std::vector<double> add_vec(double*, double*)’ [-fpermissive]
仔细理解,编译器这样做是有道理的,因为第一个重载只是第一个的特殊情况,不能包括第一个,而第二个重载却能包含第一个
更多参见:
Can a cast operator be explicit?
How do conversion operators work in C++?
- C++库研究笔记——操作符重载实现类型转换&这样做的意义
- C++库研究笔记——赋值操作符operator=的正确重载方式(三个准则)
- C++库研究笔记——赋值操作符operator=的正确重载方式(2)
- 类型转换和操作符重载 (c#)
- C++ Primer学习笔记——$14 操作符重载、函数对象及类类型转换
- 重载类型转换操作符 遇到的问题
- 【C++】强制类型转换运算符的重载
- 怎样重载强制类型转换操作符
- C++重载类型转换操作符
- C++重载类型转换操作符
- C++重载类型转换操作符
- C++重载强制类型转换操作符
- C++重载类型转换操作符
- 【正一专栏】读《怎样做社会研究》——社会研究的意义
- 操作符重载——C/C++学习笔记
- C++ 操作符重载之 类型转换 重载
- 通过运算符重载实现类型转换
- 【C/C++】C++库研究笔记——函数名的宏定义
- 线性表练习题2-5
- Ajax注册验证
- jsp乱码处理
- 神经网络
- reference schematic
- C++库研究笔记——操作符重载实现类型转换&这样做的意义
- NSInvocation 的使用小例子
- Hessian原理分析
- 中央气象局天气预报接口城市代码大全
- 线性表练习题2-6
- 80后IT男“鲜果切”年入千万元
- 城里城外看SSDT
- 浅析Web工程目录和tomcat目录
- spring mvc restful service string/json/xml