淘先锋技术网

首页 1 2 3 4 5 6 7

C++类型操作符重载示例。

代码

#include <cstdio>
#include <iostream>

class Foo {
public:
    explicit Foo(int v): value(v) {
    }

    operator double() {
        std::cout << "double()" << std::endl;
        return value * 5.0;
    }

    operator int() {
        std::cout << "int()" << std::endl;
        return value * 3;
    }

    Foo operator+(const Foo& other) {
        return Foo(value + other.value);
    }

private:
    int value;
};

int main()
{
    Foo foo(2);
    double d = foo;
    int i = foo;

    //float f = foo; // error C2440: “初始化”: 无法从“Foo”转换为“float”

    std::cout << "d:" << d <<std::endl;
    std::cout << "i:" << i <<std::endl;

    Foo foo2(2);
    Foo foo3(30);

    Foo foo5 = foo2 + foo3;
    printf("foo5: %d\n", foo5);
    printf("foo5: %d\n", (int)foo5);

    return 0;
}

运行结果

double()
int()
d:10
i:6
foo5: 32
int()
foo5: 96
请按任意键继续. . .

foo5

注意到foo5第一条printf,这里没有类型转换。

foo5

即对于结构体或class对象,以%d调用printf时,把这个对象的地址视作一个整型数据的地址。

代码

#include <cstdio>
#include <iostream>

struct Bar {
    int x;
    int y;
};

struct Bar2 {
    char c1;
    char c2;
    char c3;
    char c4;
    int x;
};

int main()
{
    struct Bar bar = {3, 2};
    struct Bar2 bar2 = {'0', '1', '2', '3', 10};

    printf("bar=%d\n", bar);
    printf("bar2=%d\n", bar2);
    printf("bar2=0x%x\n", bar2);

    return 0;
}

运行结果

bar=3
bar2=858927408
bar2=0x33323130
请按任意键继续. . .

说明

根据这个例子,可以看到printf不是类型安全的,作为对比,用cout来打印:

std::cout<<"bar2="<<bar2<<std::endl;

此时编译期即可检查出这个错误调用:

error C2679: 二进制“<<”: 没有找到接受“Bar2”类型的右操作数的运算符(或没有可接受的转换)
1>          d:\program files (x86)\microsoft visual studio 10.0\vc\include\ostream(679): 可能是“std::basic_ostream<_Elem,_Traits> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<_Elem,_Traits> &,const char *)”[通过使用参数相关的查找找到]
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
1>          d:\program files (x86)\microsoft visual studio 10.0\vc\include\ostream(726): 或       “std::basic_ostream<_Elem,_Traits> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<_Elem,_Traits> &,char)”[使用参数相关的查找找到]
1>          with
。。。。。

这个错误提示,类似于最前面例子中的float类型转换:

//float f = foo; // error C2440: “初始化”: 无法从“Foo”转换为“float”

可以想到,在最前面的例子中,下面这种写法是没有编译问题的:

printf("foo: %f\n", foo);

回到现在的例子,如果的确需要从Bar2类型转换成int类型,就需要明确定义类型操作符。即:

struct Bar2 {
    char c1;
    char c2;
    char c3;
    char c4;
    int x;

    operator int() {
        std::cout << "int()" << std::endl;
        return x;
    }
};