我们知道, 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++强制转化, 很简单, 我就不说了。


 

 

       复习到了这一块, 就先记录一下。

 

 


本文转载:CSDN博客