标签:int str today pos 拷贝 ref c++ public blank
考虑一个类Date:
class Date{ int d,m,y; //... }; void my_fact(Date d); void f() { Date d{15}; //似乎合理:x变为{15,today.m,today.y} d = 15; //含混 my_fact(15); //含混 //... }
这最多是一段含混代码,数据15和Date之间并没有清晰的逻辑关联。
但是,我们可以指明构造函数不能用作隐式类型转换。如果构造函数的声明带有关键字explicit,它只能用于初始化和显示类型转换。例如:
class Date{ int d, m, y; public: explicit Date(int dd = 0,int mm=0,int yy = 0); //... }; Date d1{15}; //OK:被看作显式类型转换 Dated2 = Date{15}; //OK:显式类型转换 Date d3 = {15}; //错误: = 方式的初始化不能进行隐式类型转换 Date d4 = 15; //错误: = 方式的初始化不能进行隐式类型转换 void f() { my_fact(15); //错误:参数传递不能进行隐式类型转换 my_fact({15}); //错误:参数传递不能进行隐式类型转换 my_fact(Date{15}); //OK:显式类型转换 }
用 = 进行初始化可以看做 拷贝初始化,一般而言,初始化器的副本会被方式待初始化的对象。但是,如果初始化器是一个右值,这种拷贝可能被优化掉(取消),而采用移动操作,省略 = 会将初始化变为显式初始化。显式初始化也称为 直接初始化。
默认情况下,应该将单参数的构造函数生命为explicit。除非有更好的理由,否则应该按照这种默认的方式去做。如果定义隐士构造函数,最好写下原因,否则代码的维护者可能怀疑你疏忽了,或者不懂这一原则。
如果一个构造函数声明为explicit且定义在类外,则在定义中不能重复explicit:
class Date{ int d,m,y; public: explicit Date(int dd); //.... }; Date::Date(int dd){/*...*/} //OK explicit Date::Date(int dd){/*...*/} //错误
大多数explicit起重要作用的构造函数都接收单一参数。但是,explicit也可以用于五参或多个参数的构造函数。例如:
struct X{ explicit X(); explicit X(int, int); }; X x1 = {}; //错误:隐式的 X x2 = {1,2}; //错误:隐式的 X x3{}; //OK:显式的 X x4{1,2}; //OK:显式的 int f(X); int i1 = f({}); //错误:隐式的 int i2 = f({1,2}); //错误:隐式的 int i3 = f(X{}); //OK:显式的 int i4 = f(X{1,2}); //OK:显式的
More:参考链接
标签:int str today pos 拷贝 ref c++ public blank
原文地址:http://www.cnblogs.com/gardenofhu/p/7596830.html