Pair
Class Pair将两个value视为一个单元
namespace std{
template<typename T,typename U>
struct pair{
T first;
U second;
...
};
}
Tuple
tuple可拥有任意类型任意数量的元素
std::tuple<int, double, char,std::string> tuple(1, 2.3, 'y', "hello wolrd");
tuple不允许迭代,运行时传入索引值将报错
std::get<i>(tuple);//错误
Smart Pointer(智能指针)
Smart Pointer能够得知本身是否为指向某个对象的最后一个指针,当其为指向某个对象的最后一个指针且被删除时即会销毁所指对象
shared_ptr
共享式拥有 多个smart pointer指向同一对象,对象和资源在最后一个smart pointer销毁时被释放
#include<iostream>
#include<string>
#include<vector>
#include<memory>
using namespace std;
int main() {
shared_ptr<string> x(new string("kyleson"));
shared_ptr<string> y(new string("monica"));
(*x)[0] = 'K';
y->replace(0, 1, "J");
vector<shared_ptr<string>> person;
person.push_back(x);
person.push_back(y);
person.push_back(x);
person.push_back(y);
for (auto ptr : person)
cout << *ptr << " ";
cout << endl;
*x = "Nonica";
for (auto ptr : person)
cout << *ptr << " ";
cout << endl;
cout << "use_count:" << person[0].use_count() << endl;//所指对象当前拥有者(指针)数量
getchar();
return 0;
}
Kyleson Jonica Kyleson Jonica
Nonica Jonica Nonica Jonica
use_count:3
当string的最后一个拥有者shared_ptr被销毁,所指对象随即调用delete
对象的delete不一定发生在 程序终点 , 将nullptr赋值给x或者调整vector大小使其只含有y,则都会调用delete
自定义delete
shared_ptr<string> x(new string("kyleson"),
[](string *p){
cout << "delete" << *p;
delete p;
});
当最后一个拥有者被销毁时,将调用该lambda函数
shared point的默认调用delete,而非delete [],当智能指针指向数组时需自定义delete
shared_ptr<int> p(new int[10], [](int *p) {delete[] p; });
shared_ptr<int> p(new int[10],std::default_delete<int[]>());//利用unique_ptr提供的辅助函数
weak_ptr
weak_ptr共享但不拥有某对象,一旦最末拥有该对象的shared_ptr失去拥有权,任何weak_ptr都会自动成空
#include<iostream>
#include<string>
#include<vector>
#include<memory>
using namespace std;
class Person {
public:
string name;
shared_ptr<Person> mother;
shared_ptr<Person> father;
vector<shared_ptr<Person>> kids;
Person(const string &name,
shared_ptr<Person> m = nullptr,
shared_ptr<Person> f = nullptr) :
name(name), mother(m), father(f) {};
~Person(){
std::cout << "delete " << name << endl;
}
};
shared_ptr<Person> initFamily(const string &name) {
shared_ptr<Person> mom(new Person(name + "'s mom"));
shared_ptr<Person> dad(new Person(name + "'s dad"));
shared_ptr<Person> kid(new Person(name, mom, dad));
mom->kids.push_back(kid);
dad->kids.push_back(kid);
return kid;
}
int main() {
shared_ptr<Person> p = initFamily("kyleson");
cout << "kyleson's family exits" << endl;
cout << "- kyleson is shared " << p.use_count() << " times" << endl;
cout << "- name of 1st kid of kyleson's mom:"
<< p->mother->kids[0]->name << endl;
p = initFamily("Ninoca");
cout << "- Ninoca is shared " << p.use_count() << " times" << endl;
getchar();
return 0;
}
kyleson's family exits
- kyleson is shared 3 times
- name of 1st kid of kyleson's mom:kyleson
- Ninoca is shared 3 times
程序结束时,并未打印”delete kyleon”或“delete Ninoca”,即未执行析构函数,Person内部存在循环指向,其对象在程序结束时仍至少被一个shared_ptr指向.
vector<weak_ptr<Person>> kids;
cout << "- name of 1st kid of kyleson's mom:"
<< p->mother->kids[0].lock()->name << endl;
kyleson's family exits
- kyleson is shared 1 times
- name of 1st kid of kyleson's mom:kyleson
delete kyleson
delete kyleson's dad
delete kyleson's mom
- Ninoca is shared 1 times
...
使用weak_ptr将会解决循环指向问题,当改变p的指向后调用了析构函数,且当程序结束时”Ninoca”的析构函数也将被调用
int *x = new int;
shared_ptr<int> sp1(x);
shared_ptr<int> sp2(x);//错误
shared_ptr<int> sp3 = sp1;//正确
问题出在sp1和sp2意味着”两个指向团队”,都会在丢失x的拥有权时释放资源,因此相应的资源会被释放两次而导致错误
class Person {
public:
...
void setParentAndTheirKids(shared_ptr<Person> m = nullptr, shared_ptr<Person> f = nullptr) {
mother = m;
father = f;
if (m != nullptr)
m->kids.push_back(shared_ptr<Person>(this));//错误 引入了新的指向团队
if (f != nullptr)
f->kids.push_back(shared_ptr<Person>(this));//错误 引入了新的指向团队
}
};
根据this建立的shared_ptr同样建立了新的”指向团队”
class Person :std::enable_shared_from_this<Person>{
public:
...
void setParentAndTheirKids(shared_ptr<Person> m = nullptr, shared_ptr<Person> f = nullptr) {
mother = m;
father = f;
if (m != nullptr)
m->kids.push_back(shared_from_this());
if (f != nullptr)
f->kids.push_back(shared_from_this());
}
};
unique_ptr
独占式拥有 同一时间只有一个smart pointer指向该对象
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!