码迷,mamicode.com
首页 > 编程语言 > 详细

C++

时间:2017-09-26 16:01:28      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:int   str   today   pos   拷贝   ref   c++   public   blank   

explicit构造函数

考虑一个类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:参考链接

C++

标签:int   str   today   pos   拷贝   ref   c++   public   blank   

原文地址:http://www.cnblogs.com/gardenofhu/p/7596830.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!