C++库研究笔记——操作符重载实现类型转换&这样做的意义

目标:

已知这个接口:

 

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++?

 

 

 

你可能感兴趣的:(类型转换)