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指向该对象



C++      C++

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!