explicit修饰的构造函数:
1.不能使用隐式的类型转换。
2.必须使用直接初始化形式。
能够通过一个实参调用的构造函数定义了一条从构造函数的参数类型向类类型隐式转换的规则。
string null_book = "9-999-99999-9";
//构造一个临时的sales_data对象
item.combine(null_book);
上面,item是之前定义好的一个对象,它的combine函数本来是接受一个sales_data类型的对象的,但是现在我们将string类型的null_book传递给这个函数,原因是 sales_data的其中一个构造函数接受string类型的参数 且 仅有这一个参数,所以,就存在一个string 像sales_data隐式转换的规则。 在传参过程中先是null_book隐式的转换为了sales_data的临时对象,再将这个临时对象传递给combine函数。
关键词 explicit就是用来抑制这种操作的
- 智能指针的构造函数存在一个只接收内置指针的形式。但是是被explicit修饰的。
share_ptr<int> p(new int(42)); //正确 与构造函数的要求完全一致。
share_ptr<int> p = new int(42); //错误 这样的隐式转换在智能指针中不能完成。
shared_ptr<int> p(new int(42));
int *q = p.get();
{
shared_ptr<int>(q);
}
int foo = *p;
return 0;
以上代码可以正常运行。但是有问题
p = new int(1024); //错误 不能将一个指针直接赋值给shared_sptr不存在这样的隐式转换
p.reset(new int(1024)); //正确 p指向一个新对象
if(!p.unique())
p.reset(new string(*p)); //如果不是唯一的 从新赋值一个
*p += newVal; //已知是唯一的情况下 进行操作
练习12.10:下面的代码调用了第413页中定义的process函数,解释此调用是否正确。如果不正确,应该如何修改?
shared_ptr<int> p(new int(42));
process(shared_ptr<int>(p));
答:正确 这样做 猜想 shared_ptr<int>(p) 相当于是做了一次数据类型转换的操作,由于这里是一样的数据类型所以加了等于没加。关于类之间怎么做数据类型转换 这个问题我还不太明白 先记在这里吧
用一个shared_ptr初始化另一个shared_ptr时。
将一个shared_ptr作为参数传递时。
函数返回一个shared_ptr时。
练习 12.11:如果我们像下面这样调用process,会发生什么?
process(shared_ptr<int>(p.get()));
答 这样的话就相当于重新定义了一个智能指针 并作为参数传给函数 且其次数只有一次当他退出后 会释放内存导致原指针内存被释放。
练习12.12:p和q的定义如下,对于接下来的对process的每个调用,如果合法,解释它做了什么,如果不合法,解释错误原因:
auto p = new int();
auto sp = make_shared<int>();
(a) process(sp); //没问题 常规调用
(b) process(new int()); // 错 不存在这样的类型转换
(c) process(p); // 错 不存在这样的类型转换
(d) process(shared_ptr<int>(p)); //对 经过转换后的可以用
练习12.13:如果执行下面的代码会发生什么?
auto sp = make_shared<int>();
auto p = sp.get();
delete p;
答 会释放掉 智能指针和内置指针共同指向的空间导致智能指针指向的位置被释放。