文档章节

C++11 智能指针

y
 yepanl
发布于 09/24 21:35
字数 868
阅读 34
收藏 0

    C++11提供了三个智能指针,std::shared_ptr,std::unique_ptr,std::weak_ptr。最常用的是shared_ptr和unique_ptr。

    (1)std::shared_ptr

            shared_ptr是共享指针,通过在控制块中增加引用计数的方式实现多个指针指向同一个对象。每当拷贝构造或者拷贝赋值时,对象的引用计数都会+1,每当指针对象析构时,引用计数-1,直到引用计数为0,释放实际指针对象。

            std::shared_ptr<T> sp(new T()) 形式声明效率上没有 std::shared_ptr<T> sp = std::make_shared<T>()高,因为前一种声明方式在实现上需要new两次(一次是new T, 一次是 new 控制结构),而后者在实现上一般都是一次。

示例如下:

#include <iostream>
#include <memory>

int main() {
    {
        std::shared_ptr<int> sp1;

        {
            std::shared_ptr<int> sp2(new int(10));
            sp1 = sp2;
            std::cout << "sp1.count=" << sp1.use_count() << std::endl;    // use_count为2
        }
        std::cout << "sp1.count=" << sp1.use_count() << std::endl;        // use_count为1
    }

    return 0;
}

 

    2,std::unique_ptr

        unique_ptr顾名思义,只允许一个指针指向同一个对象。unique_ptr通过禁止拷贝构造函数和拷贝赋值运算符到达无法让多个指针指向同一个对象的目的。unique_ptr通过移动构造函数和移动赋值运算符达到指针对象资源转移的目的(保证某一时刻只有一个指针指向该对象)。

        同样,std::unique_ptr<T> sp(new T()) 形式声明效率上没有 std::unique_ptr<T> sp = std::make_unique<T>()高,因为前一种声明方式在实现上需要new两次(一次是new T, 一次是 new 控制结构),而后者在实现上一般都是一次。

示例如下:

#include <iostream>
#include <memory>

int main() {
    std::unique_ptr<int> sp1(new int(10));
//    std::unique_ptr<int> sp2 = sp1;                    // 编译错误,拷贝构造函数 deleted
    std::unique_ptr<int> sp2 = std::move(sp1);    // ok,使用移动构造函数,实现资源转移

    return 0;
}
 

    3,std::weak_ptr

        std::shared_ptr在循环引用的情况下会有内存泄漏的问题,示例如下:

#include <iostream>
#include <memory>

class Child;
class Parent;

class Parent {
private:
    std::shared_ptr<Child> ChildPtr;

public:
    void setChild(std::shared_ptr<Child> child) {
        this->ChildPtr = child;
    }

    ~Parent() {}
};

class Child {
private:
    std::shared_ptr<Parent> ParentPtr;

public:
    void setPartent(std::shared_ptr<Parent> parent) {
        this->ParentPtr = parent;
    }

    ~Child() {}
};

int main() {
    std::weak_ptr<Parent> wpp;
    std::weak_ptr<Child> wpc;
    {
        std::shared_ptr<Parent> p(new Parent);
        std::shared_ptr<Child> c(new Child);
        p->setChild(c);
        c->setPartent(p);
        wpp = p;
        wpc = c;
        std::cout << p.use_count() << std::endl; // 2
        std::cout << c.use_count() << std::endl; // 2
    }
    std::cout << wpp.use_count() << std::endl;  // 1
    std::cout << wpc.use_count() << std::endl;  // 1
    return 0;
}
    说明:本质上来说,由于循环相互引用,导致双方都没有减少对方的引用计数,导致双方资源都没有释放掉。

    std::weak_ptr提供了一种资源监视的方法:使用weak_ptr指向一个shared_ptr,并不会增加对象的引用计数,但是可以访问shared_ptr的控制块结构。解决上述循环引用问题的示例代码如下:

    

#include <iostream>
#include <memory>

class Child;
class Parent;

class Parent {
private:
    std::shared_ptr<Child> ChildPtr;

public:
    void setChild(std::shared_ptr<Child> child) {
        this->ChildPtr = child;
    }

    ~Parent() {}
};

class Child {
private:
//    std::shared_ptr<Parent> ParentPtr;
    std::weak_ptr<Parent> ParentPtr;

public:
    void setPartent(std::shared_ptr<Parent> parent) {
        this->ParentPtr = parent;
    }

    ~Child() {}
};

int main() {
    std::weak_ptr<Parent> wpp;
    std::weak_ptr<Child> wpc;
    {
        std::shared_ptr<Parent> p(new Parent);
        std::shared_ptr<Child> c(new Child);
        p->setChild(c);
        c->setPartent(p);
        wpp = p;
        wpc = c;
        std::cout << p.use_count() << std::endl;   // 1
        std::cout << c.use_count() << std::endl;   // 2
    }
    std::cout << wpp.use_count() << std::endl;  // 0
    std::cout << wpc.use_count() << std::endl;  // 0
    return 0;
}
 

© 著作权归作者所有

共有 人打赏支持
y
粉丝 0
博文 56
码字总数 55172
作品 0
南京
程序员
私信 提问
linux之让终端支持C++11/14编译cpp文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011068702/article/details/83692312 1 问题 我们的项目很多智能指针,但是我linux的终端肯定不支持C++11/14,...

chenyu_insist
11/03
0
0
C++11 智能指针

原作者:BabuAbdulsalam 本文翻译自CodeProject,转载请注明出处。 引入 尽管有另外一篇文章说里的智能指针了。近来,我听到许多人谈论新标准,就是所谓的。 我研究了一下的一些语言特性,发...

2017/12/28
0
0
C++ 11和C++98相比有哪些新特性

此文是如下博文的翻译: https://herbsutter.com/elements-of-modern-c-style/ C++11标准提供了许多有用的新特性。这篇文章特别针对使C++11和C++98相比看上去像一门新语言的特性,因为: C+...

harlanc
2017/03/05
0
0
消灭“脑细胞杀手”,阿里专家带你深入C++对象的生命周期管理

摘要:C/C++的指针一直是令人又爱又恨的特性。围绕指针产生了许许多多优雅的数据结构和系统实现,但又滋生了不少“脑细胞杀手”——内存Bug。C/C++指针问题(空指针、野指针、垂悬指针)的根...

萌萌怪兽
04/18
0
0
一个函数指针模板,向std::function致敬

两年前写这个是因为学C++11练手。而且也因为sizeof(std::function<void()>)的大小有点大,不是指针大小。所以自己写个只有指针大小的版本,不过功能就少很多。 这样就可以这么用: 基本的思路...

大止刀口
2016/05/02
255
0

没有更多内容

加载失败,请刷新页面

加载更多

中国龙-扬科
31分钟前
2
0
使用vuex的state状态对象的5种方式

vuex是一个专门为vue.js设计的状态管理模式,并且也可以使用devtools进行调试。 下面给大家来贴一下我的vuex的结构 下面是store文件夹下的state.js和index.js内容 //state.jsconst state =...

peakedness丶
35分钟前
2
0
NetCore MVC Demo

地址:http://114.116.9.72:5411

whltian
42分钟前
3
0
Netty handle方法周期 (四)

写了一个练习之后,发现自定义的助手类每次肯定是必须的,对于不同的业务逻辑需求,会写相对应的逻辑 最简单的查看Handle生命周期的方式,就是重写上级方法,看名字差不多应该可以知道方法的作用 ...

_大侠__
47分钟前
9
0
vue主动刷新页面及列表数据删除后的刷新实例

1.场景 在处理列表时,常常有删除一条数据或者新增数据之后需要重新刷新当前页面的需求。 2.遇到的问题 1. 用vue-router重新路由到当前页面,页面是不进行刷新的 2.采用window.reload(),或者...

前端小攻略
58分钟前
16
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部