Cpp 杂记 explicit shared_ptr

explicit 修饰constructor

比较区别:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 无explicit
class foo{
public:
foo(int n){ num_ = n; }
private:
int num_;
};
// 有explicit
class bar{
public:
explicit bar(int n){ num_ = n; }
private:
int num_;
};

int main() {
foo f1(2); // correct
foo* f2 = new foo(2); // correct
foo f3 = 2; // correct


bar b1(3); // correct
bar* b2 = new bar(3); // correct
bar b3 = 3; // incorrect
}

bar b3 = 3含义是,3的类型int正好是bar单参数构造函数的参数类型int,这时候编译器就自动调用这个构造函数,创建一个bar的对象。这在explicit修饰下是不可行的,只能显式地以3为参数传给构造函数。

shared_ptr<>

理解shared_ptr可以这样理解:
对于std::shared_ptr<string> ptr(new string),这里有两个对象,“我”和“你”(均为指针)。“我”是ptr,而“你”对应了new string。这时“我”和“你”就有了关系,“我”管理“你”。当new string即“你”不存在时,我不管理任何人,即我管理一个空指针。

定义并初始化

定义一个空共享指针,指向类型为int的对象, owns no pointer(“我”没有管理任何指针), 由于ptr1是空指针,所以为ptr1所指向的对象赋值是违法的:segmentation fault

1
2
3
4
5
std::shared_ptr<string> ptr1; 
if (!ptr1)
cout<<"ptr1==NULL"<<endl;
// 违法,因为ptr1没有指向任何对象,所以给对象赋值是逻辑错误
*ptr1 = "string ptr1";

初始化一个shared_ptr ptr2,非空指针,指向“”。此后,ptr2 就可以像string* 类型的指针一样使用。ptr2 可以管理使用new 关键字分配出来的指针。(new 出来的一定是个指针

1
2
3
4
// ptr2 管理一个指向string的指针
std::shared_ptr<string> ptr2(new string);
*ptr2 = "string ptr2";
cout<<*ptr2<<endl;

常用的初始化方法:

1
2
3
4
5
6
7
// 一般的初始化一个shared_ptr方法
std::shared_ptr<string> ptr3(new string("string ptr3"));
cout<<*ptr3<<endl;

// 推荐的初始化一个shared_ptr
std::shared_ptr<string> ptr4 = make_shared<string>("string ptr4");
cout<<*ptr4<<endl;

成员方法

ptr.get()方法,它返回一个指针,这个指针指向ptr所指向对象:

1
2
string* p = ptr4.get();
cout<<*p<<endl;

ptr.reset()方法,改变ptr所指向内容。这里有个好例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
std::shared_ptr<int> sp;  // empty 

// 管理一个指针
sp.reset (new int);
*sp=10;
std::cout << *sp << '\n';

// 删除所管理的指针, 干礼一个新指针
sp.reset (new int);
*sp=20;
std::cout << *sp << '\n';

// 删除所管理的指针
sp.reset();

以下情况相同:

1
2
3
4
5
6
ptr4.reset(new string("string reset ptr4"));
cout<<*ptr4<<endl;

string* pp = new string("fuck you");
ptr4.reset(pp);
cout<<*ptr4<<endl;