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,这里没有类型转换。
即对于结构体或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;
}
};