C++能够定义如何将其余类型的对象隐式转换为咱们的类类型或将咱们的类类型的对象隐式转换为其余类型。为了定义到类类型的隐式转换,须要定义合适的构造函数。ios
说明:能够用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换。app
class Sales_item { public: Sales_item(const string &book = "") : isbn(book), units_sold(0), revenue(0.0) {} Sales_item(istream &is); };
这两个构造函数都定义了一个隐式转换。所以,在期待一个Sales_item类型对象的地方可使用一个string或一个istream对象。函数
string null_book = "9-999-99999-9"; item.Same_isbn(null_book);
这段代码使用一个string类型对象做为实参传递给Sales_item的Same_isbn成员函数,该成员函数期待一个Sales_item对象做为实参。编译器将使用接受一个string的构造函数从null_book生成一个新的Sales_item对象。新生成的(临时的)Sales_item对象被传递给Same_isbn。测试
item.Same_isbn(cin);
这段代码将cin对象隐式转换为Sales_item对象,这个转换执行接受一个istream的构造函数。这两个Sales_item是临时对象,一旦Same_isbn结束,就不能再访问它。ui
下面看一个例子:http://blog.csdn.net/vagrxie/article/details/1586340spa
1 #include <string> 2 #include <iostream> 3 using namespace std; 4 5 class Fruit //定义一个类,名字叫Fruit 6 { 7 string name; //定义一个name成员 8 string colour; //定义一个colour成员 9 10 public: 11 bool isSame(const Fruit &otherFruit) //期待的形参是另外一个Fruit类对象,测试是否同名 12 { 13 return name == otherFruit.name; 14 } 15 void print() //定义一个输出名字的成员print() 16 { 17 cout<<colour<<" "<<name<<endl; 18 } 19 Fruit(const string &nst,const string &cst = "green"):name(nst),colour(cst){} //构造函数 20 21 Fruit(){} 22 }; 23 24 int main(void) 25 { 26 Fruit apple("apple"); 27 Fruit orange("orange"); 28 cout<<"apple = orange ?: "<<apple.isSame(orange)<<endl; //没有问题,确定不一样 29 cout<<"apple = apple ?:"<<apple.isSame(string("apple"))<<endl; //用一个string作形参? 30 31 return 0; 32 }
咱们用string("apple")类型做为一个期待Fruit类型形参的函数的参数,结果是正确的。当把构造函数colour的默认实参去掉,也就是定义一个对象必需要两个参数的时候,文件编译不能经过。Fruit apple("apple")其实也已经有了一个转换,从const char *的C字符串格式,转为string。但apple.isSame("apple")这样调用确定是错的,必需要用string()来先强制转换,而后系统才知道帮你从string隐式转换为Fruit。固然你也能够显式帮它完成,apple.isSame(Fruit("apple"))。.net
能够经过将构造函数声明为explicit,来防止在须要隐式转换的上下文中使用构造函数。explicit关键字只能用于类内部的构造函数声明上。在类的定义体外部所作的定义再也不重复它。虽然不能隐式转换了,但显式转换仍是能够的,例如:apple.isSame(Fruit("apple"))。code
说明:对象
(1)显式使用构造函数只是终止了隐式地使用构造函数。任何构造函数均可以用来显式地建立临时对象。blog
(2)一般,除非有明显的理由想要定义隐式转换,不然,单形参构造函数应该为explicit。将构造函数设置为explicit能够避免错误,而且当转换有用时,用户能够显式地构造对象。
(3)将构造函数设置为explicit的好处是能够避免因隐式类型转换而带来的语义错误,缺点是当用户的确须要进行相应的类型转换时,不能依靠隐式类型转换,必须显式地建立临时对象。