1.无符号数和有符号数相加,会将有符号数隐式转换为无符号数
#include <string>
#include <sstream>
using namespace std;
int main() {
short s = 'a';
unsigned int ui = 1000;
int i = -2000;
double d = i;
cout << "d=" << d << endl; //-2000
cout << "ui=" << ui << endl; //1000
cout << "ui+i=" << ui + i << endl;
if ((ui + i) > 0) {
cout << "Positive" << endl;
}
else {
cout << "Negative" << endl;
}
return 0;
}
运行结果:
d=-2000
ui=1000
ui+i=4294966296
Positive
所以在进行运算时我们要避免隐式类型转换
short s = 'a';
cout << "sizeof(s+'b')" << sizeof(s + 'b') << endl; //4
会将short类型和char类型都默认 转换为int
2.普通类型和类类型之间是否能进行转换?
(1)构造函数可以定义不同类型的参数
(2)参数满足下列条件时称为转换构造函数:
有且只有一个参数、参数是基本类型或其他类型
Test t; t=100;——>默认等价于:t=Test(100)
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Test {
int mValue;
public:
Test() {
mValue = 0;
}
Test(int i) {
mValue = i;
}
Test operator+(const Test& p) {
Test ret(mValue + p.mValue);
return ret;
}
int value() {
return mValue;
}
};
int main() {
Test t;
t = 5; // t=Test(5)
Test r;
r = t + 10; // r=t+Test(10)
cout << r.value() << endl;
return 0;
}
编译器会尽力进行隐式类型转换,也有可能会产生bug
3.工程中通过explicit关键字杜绝编译器的转换尝试,转换构造函数被explicit修饰时只能进行显示转换,转换方式:
(1)static_cast<ClassName>(value); 推荐写法
(2)ClassName(value); 相当于手工调用构造函数
(3)(ClassName)value; 不推荐
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Test {
int mValue;
public:
Test() {
mValue = 0;
}
explicit Test(int i) {
mValue = i;
}
Test operator+(const Test& p) {
Test ret(mValue + p.mValue);
return ret;
}
int value() {
return mValue;
}
};
int main() {
Test t;
// t = 5; // 报错,因为构造函数前加了explicit,不能进行隐式转换,要想转换需要强制转换
t = (Test)5;
//或者写成t = static_cast<Test>(5);
Test r;
// r = t + 10; // 报错,原因一样
r = t + Test(10);
//或者写成r = t + static_cast<Test>(10);
cout << r.value() << endl;
return 0;
}
4.类类型是否能类型转换到普通类型?
(1)C++类中可以定义类型转换函数
(2)类型转换函数用于将类对象转换为其他类型
语法:
operator Type() {
Type ret;
// ...
return ret;
}
(1)类型转换函数与转换构造函数具有同等的地位
(2)编译器能够隐式的使用类型转换函数
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Test {
int mValue;
public:
Test(int i = 0) {
mValue = i;
}
int value() {
return mValue;
}
operator int() {
return mValue;
}
};
int main() {
Test t(100);
int i = t;
cout << "t.value()=" << t.value() << endl; //100
cout << "i=" << i << endl; //100
return 0;
}
其中int i=t;隐式调用了成员函数,即int i=t.operator int();
5.类类型之间的转换
在Test类中定义类型转换函数:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Value {
public:
Value() {
}
};
class Test {
int mValue;
public:
Test(int i = 0) {
mValue = i;
}
int value() {
return mValue;
}
operator int() {
return mValue;
}
operator Value() {
Value ret;
return ret;
}
};
int main() {
Test t(100);
Value v = t;
return 0;
}
或者在Value类中定义转换构造函数
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Test;
class Value {
public:
Value() {
}
Value(Test& t) {
}
};
class Test {
int mValue;
public:
Test(int i = 0) {
mValue = i;
}
int value() {
return mValue;
}
operator int() {
return mValue;
}
};
int main() {
Test t(100);
Value v = t; //等价于Value(t)
return 0;
}
若在Test和Value类中都定义了相关转换函数,则会报错,编译器会有两个选择,出现歧义
所以这种隐式转换可能会发生类型转换函数与转换构造函数冲突,所以我们需要在其中一个转换函数前加关键字explicit,则编译器只会选择另一个不加关键字的函数进行调用
在工程中以Type toType()的公有成员代替类型转换函数
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Test;
class Value {
public:
Value() {
}
explicit Value(Test& t) {
}
};
class Test {
int mValue;
public:
Test(int i = 0) {
mValue = i;
}
int value() {
return mValue;
}
Value toValue() {
Value ret;
cout << "operator Value()" << endl;
return ret;
}
};
int main() {
Test t(100);
Value v = t.toValue(); //operator Value()
return 0;
}

794

被折叠的 条评论
为什么被折叠?



