我们知道, int, float,doulbe等之间可以进行隐式的转换, 那么这些内置类型可以转化为类类型么? 我们来看看程序吧:
#include <iostream>
using namespace std;
class A
{
public:
int x;
int y;
int z;
public:
A()
{
cout << "default" << endl;
}
A(int xx)
{
cout << "oh" << endl;
}
A(ostream &os)
{
os << "good" << endl;
}
void test(const A &a)
{
cout << "ok" << endl;
cout << a.x << endl;
cout << a.y << endl;
cout << a.z << endl;
}
};
int main()
{
A a;
cout << a.x << endl;
cout << a.y << endl;
cout << a.z << endl;
a.test(1); // 1被隐式转化成一个临时对象
a.test(cout); // cout 被隐式转化成一个临时对象
return 0;
}
结果为:
default
-858993460
-858993460
-858993460
oh
ok
-858993460
-858993460
-858993460
good
ok
-858993460
-858993460
-858993460
我们看到, 有转换了。 要注意, 如果构造函数只有一个实参, 则它实际上定义了转化为此类型的隐式转换机制, 此时的构造函数充当为转换构造函数。
我们再看:
#include <iostream>
#include <string>
using namespace std;
class A
{
public:
string s;
public:
A()
{
cout << "default" << endl;
}
A(string s)
{
cout << "oh" << endl;
}
A(ostream &os)
{
os << "good" << endl;
}
void test(const A &a)
{
cout << "ok" << endl;
}
};
int main()
{
A a;
a.test("goodddd")); // error, 需要两部转换
a.test(cout);
return 0;
}
为什么这个程序是错误的呢? 因为原则上每次仅允许一步类类型转换, 上面涉及到两次转换。 所以, 可以考虑把隐式转换分开, 做两步伐。 当然啦, 也可以把上述程序中的"goodddd"改成string("goodddd"), 这样就是先显式后隐式了。
好, 我们继续看, 有没有一种方式让编译器直接拒绝所谓的隐式转换呢? 有, 如下:
#include <iostream>
#include <string>
using namespace std;
class A
{
public:
string s;
public:
A()
{
cout << "default" << endl;
}
explicit A(string s) // 要求必须是显式转换
{
cout << "oh" << endl;
}
A(ostream &os)
{
os << "good" << endl;
}
void test(const A &a)
{
cout << "ok" << endl;
}
};
int main()
{
A a;
string s = "xxxx";
a.test(s); // error
a.test(cout);
return 0;
}
explicit关键期强迫程序猿采用显式转化, 所以, 上面程序应该修改为:
#include <iostream>
#include <string>
using namespace std;
class A
{
public:
string s;
public:
A()
{
cout << "default" << endl;
}
explicit A(string s) // 要求必须是显式转换
{
cout << "oh" << endl;
}
A(ostream &os)
{
os << "good" << endl;
}
void test(const A &a)
{
cout << "ok" << endl;
}
};
int main()
{
A a;
string s = "xxxx";
a.test(static_cast<A>(s)); // ok
a.test(cout);
return 0;
}
当然啦, 你也可以用旧版的C/C++强制转化, 很简单, 我就不说了。
复习到了这一块, 就先记录一下。