14.9 Overloading,Conversions,and Operators(重载,转换,操作符)

一个转换运算符是一种特殊的成员函数---转换一个类类型值到其他类型

 

一个转换构造函数必须是成员函数,并且不可能有特殊的返回值,必须有一个空参列表。这个函数通常是const

 

 

#include <iostream>

using namespace std;

class A {
public:
    A(int m = 5) :i(5) {
        if (m < 0 || m > 222) {
            throw out_of_range("bad value!");
        }
    }
    //operator int*()const { return i; }//error:i不为指针类型
    //operator int(int = 0) const;//error:需要空参列表
    //operator int()const { return i; }
   explicit operator int()const { return i; }//int为返回类型
private:
    size_t i;
};

int main()
{
    A a = 5;
    //a + 3;隐式调用
    static_cast<int>(a) + 3;//显示请求调用

    system("PAUSE");
    return 0;
}

 

定义转换到bool类型,并不稀有,比如下面这段代码有时便是合法的:

int i = 5;
cin << i;//转换为bool

 

一个显式转换将会被用来隐式转换下面这些:

  • if,while,或者do条件语句
  • 在for语句中的条件表达式
  • 对于逻辑NOT(!), OR(||), 或者AND(&&)的操作对象
  • 在一个条件操作符(?:)中
while(std::cin >> val)//std::cin将会被istream operator bool隐式转换为bool

 

一般来讲operator bool一般是显示

 

通常来讲,定义一个多元转换/定义转换/形成两种算术类型。

 

#include <iostream>

using namespace std;

struct B;
struct A {
    A() = default;
    A(const B&);//转换B到A
};
struct B {
    operator A()const;//转换B到A
};

A f(const A&);
B b;
A a = f(b);//error:目标不明确

 

正确调用:

A c = f(b.operator A());
A d = f(A(b));

 

注意在这里我们不能使用cast,cast也会造成目标不明确(二义性)

 

在类似于上面的转换构造函数中,参数列表形参对于实参匹配时的类型转换在同一等级也会引起二义性。

 

需要使用一个构造函数或者转换一个参数去频繁调用一个重载函数是一个坏的设计。

 

当调用重载函数时,如果需要额外的标准类型转换,那么只有当所有可用函数请求相同的用户定义类型转换时,转换级别才有用。如果需要多个用户定义的类型转换,则此调用是不明确的。

 

a.operator(b);//a做成员函数
operator(a, b)//普通函数
posted @ 2018-12-18 01:01  Hk_Mayfly  阅读(156)  评论(0)    收藏  举报