C++基础::shared_ptr 编程细节(一)

来源:互联网 发布:视频观看软件 编辑:程序博客网 时间:2024/06/07 20:41

C++基础::shared_ptr 编程细节(一)

C++基础::shared_ptr 编程细节(二)

C++基础::shared_ptr 编程细节(三)

智能指针是c++ 中管理资源的一种方式,用智能指针管理资源,不必担心资源泄露,将 c++ 程序员从指针和内存管理中解脱出来。

shared_ptr 的两面性

  • shared_ptr 型智能指针对象的本质是类实例;

    所以允许.+成员函数的调用方式(这里的成员函数是 shared_ptr 作为类实例所具有的成员函数),比如一个shared_ptr最为类实例的成员函数:

    • .use_count()
    • .get()
    • .reset()
    • .unique()
  • 含义上作为智能指针的一面

    所以允许->成员函数的调用方式(这里的成员函数为智能指针所维护的真实对象所具有的成员函数)。

shared_ptr 的副作用

shared_ptr:一种智能指针,本意封装原生指针(new 出来的堆对象),实现指针的类型安全,然而,见名知意,它是共享型指针,即允许多个shared_ptr“指向”同一个对象,当我们在某些情况下不需要这一看似美好的性质时,该如何处理呢。

class Item{private:    std::string _name;    float _price;public:    Item(const std::string& name, float price):_name(name),                             _price(price){}    float getPrice() const { return _price;}    void setPrice(float price) { _price = price;}    Item* clone() const { return new Item(*this);} };// 单纯为了演示的需要,并无实际的意义class A{public:    A(const std::shared_ptr<Item>& obj):_obj(obj){}    const std::shared_ptr<Item>& get() const    { return _obj;}private:    std::shared_ptr<Item> _obj;};int main(int, char**){    std::shared_ptr<Item> item1(new Item("C++", 20.));    A a(item1);    // 此时查看item1的引用次数:    std::cout << item1.use_count() << std::endl;                            // 2    // 如果使用对象a对内部的_obj进行修改,会同步到item1中    a.get()->setPrice(30.);    std::cout << item1->getPrice() << std::endl;    // 这时我们创建另外一个A对象    A b(a);    // 这时如果不对A的拷贝构造进行重载的话,b也会持有一份对item1对象的引用    std::cout << item1.use_count() << std::endl;                            // 3    return 0;}

这就是shared_ptr共享型智能指针的便捷和局限。那么,我们该如何使用拷贝构造时,建立自己独特的副本呢?

我们需要显式地给出A的拷贝构造,避免编译器对拷贝构造的默认实现:

class A{...public:    A(const A& other)    {        _obj = std::shared_ptr<Item>(other.get()->clone());    } }

所以结论是,在一个需被 shared_ptr 封装的类内部给出非常关键 clone() 函数的实现非常关键

    Obj* clone() const { return new Obj(*this); }

以 shared_ptr 类类型为容器类型的容器之间的赋值

是继续持有对象的引用,还是一份全新的拷贝;

std::shared_ptr<Item> item1(new Item("C++", 20.5));std::shared_ptr<Item> item2(new Item("Python", 25.5));std::vector<std::shared_ptr<Item>> v1 = {item1, item2};std::vector<std::shared_ptr<Item>> v2 = v1;                            // 继续持有引用std::cout << item1.use_count() << std::endl;                            // 3item1->setPrice(30.);std::cout << v2[0]->getPrice() << std::endl;std::vector<std::shared_ptr<Item>> v3;for (size_t i = 0; i < v1.size(); ++i)    v3.push_back(std::shared_ptr<Item>(v1[i]->clone()));                            // 一份全新的拷贝item2->setPrice(35.5);std::cout << v3[1]->getPrice() << std::endl;                            // 25.5
0 0
原创粉丝点击