函数指针 ++++函数对象+++++智能指针++++++++++

(*fq)(12)显式的解引用

fq(12)隐式的解引用,结果相同 

 

 

  函数具有可赋值给指针的物理内存地址,一个函数的函数名就是一个指针,它指向函数的代码。一个函数的地址是该函数的进入点,也是调用函数的地址。函数的调用可以通过函数名,也可以通过指向函数的指针来调用。函数指针还允许将函数作为变元传递给其他函数。

 

 

      不带括号和变量列表的函数名,这可以表示函数的地址,正如不带下标的数组名可以表示数组的首地址。

定义形式:

        类型 (*指针变量名)(参数列表);

例如:

        int (*p)(int i,int j);

    p是一个指针,它指向一个函数,该函数有2个整形参数,返回类型为int。p首先和*结合,表明p是一个指针。然后再与()结合,表明它指向的是一个函数。指向函数的指针也称为函数指针。

 

 

        例1:

 

 

 

 
  1. #include <stdio.h>

  2.  
  3. #define GET_MAX 0

  4. #define GET_MIN 1

  5.  
  6. int get_max(int i,int j)

  7. {

  8. return i>j?i:j;

  9. }

  10.  
  11. int get_min(int i,int j)

  12. {

  13. return i>j?j:i;

  14. }

  15.  
  16. int compare(int i,int j,int flag)

  17. {

  18. int ret;

  19.  
  20. //这里定义了一个函数指针,就可以根据传入的flag,灵活地决定其是指向求大数或求小数的函数

  21. //便于方便灵活地调用各类函数

  22. int (*p)(int,int);

  23.  
  24. if(flag == GET_MAX)

  25. p = get_max;

  26. else

  27. p = get_min;

  28.  
  29. ret = p(i,j);

  30.  
  31. return ret;

  32. }

  33.  
  34. int main()

  35. {

  36. int i = 5,j = 10,ret;

  37.  
  38. ret = compare(i,j,GET_MAX);

  39. printf("The MAX is %d\n",ret);

  40.  
  41. ret = compare(i,j,GET_MIN);

  42. printf("The MIN is %d\n",ret);

  43.  
  44. return 0 ;

  45. }

 

        例2:

 

 
  1. #include <stdio.h>

  2. #include <string.h>

  3.  
  4. void check(char *a,char *b,int (*cmp)(const char *,const char *));

  5.  
  6. main()

  7. {

  8. char s1[80],s2[80];

  9. int (*p)(const char *,const char *);

  10.  
  11. //将库函数strcmp的地址赋值给函数指针p

  12. p=strcmp;

  13.  
  14. printf("Enter two strings.\n");

  15. gets(s1);

  16. gets(s2);

  17.  
  18. check(s1,s2,p);

  19. }

  20.  
  21. void check(char *a,char *b,int (*cmp)(const char *,const char *))

  22. {

  23. printf("Testing for equality.\n");

  24. //表达式(*cmp)(a,b)调用strcmp,由cmp指向库函数strcmp(),由a和b作调用strcmp()的参数。

  25. //调用时,与声明的情况类似,必须在*cmp周围使用一对括号,使编译程序正确操作,

  26. //同时这也是一种良好的编码风格,指示函数是通过指针调用的,而不是函数名。

  27. if((*cmp)(a,b)==0)

  28. printf("Equal\n");

  29. else

  30. printf("Not Equal\n");

  31. }


        例3:

 

 

 
  1. #include <stdio.h>

  2. #include <ctype.h>

  3. #include <stdlib.h>

  4. #include <string.h>

  5.  
  6. //check()函数的第3个函数是函数指针,就可以根据具体情况传入不同的处理函数

  7. void check(char *a,char *b,int (*cmp)(const char *,const char *));

  8.  
  9. //自定义的比较两个字符串的函数

  10. int compvalues(const char *a,const char *b);

  11.  
  12. main()

  13. {

  14. char s1[80],s2[80];

  15.  
  16. printf("Enter two values or two strings.\n");

  17. gets(s1);

  18. gets(s2);

  19.  
  20. //如果是数字,则用函数指针传入数字比较函数进行处理

  21. if(isdigit(*s1)){

  22. printf("Testing values for equality.\n");

  23. check(s1,s2,compvalues);

  24. }

  25. //如果是字符串,则用函数指针传入库函数strcmp进行处理

  26. else{

  27. printf("Testing strings for equality.\n");

  28. check(s1,s2,strcmp);

  29. }

  30. }

  31.  
  32. void check(char *a,char *b,int (*cmp)(const char *,const char *))

  33. {

  34. if((*cmp)(a,b)==0)

  35. printf("Equal.\n");

  36. else

  37. printf("Not Equal.\n");

  38. }

  39.  
  40. int compvalues(const char *a,const char *b)

  41. {

  42. if(atoi(a)==atoi(b))

  43. return 0;

  44. else

  45. return 1;

  46. }


注意:

 

 

        int *f(int i, int j);

        int (*p)(int i, int j);

    前者是返回值是指针的函数;后者是一个指向函数的指针。

 

 

====================================================================================================================================================================================================================================================================================================================================================================

 

 

函数指针和回调函数

函数指针

  函数指针是指向函数调用地址的指针。它和函数名究竟有什么关系呢?且看下文。

且看一小程序

  首先,先请看下边程序:

复制代码

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 void func(string s)
 6 {
 7     cout << s << endl;
 8 }
 9 
10 void (*pFunc)(string s);    // 不能够写成 void *pFunc(string s); 
11                             // 继续看下文解释
12 
13 int main()
14 {
15     cout << endl;
16     func("Original Function : 1st circumstance!");
17     (*func)("Original Function : 2nd circumstance!");
18 
19     cout << endl;
20     pFunc = &func;
21     (*pFunc)("Function pointer : 1st circumstance!");
22     pFunc("Function pointer : 2nd circumstance!");
23 
24     cout << endl;
25     pFunc = func;
26     (*pFunc)("Function pointer : 3rd circumstance!");
27     pFunc("Function pointer : 4th circumstance!");
28 
29     return 0;
30 }

复制代码

  程序的运行结果如下:

  

 

  从上边程序,我们可以得到下边结论

  1. 函数指针和函数名本质上是一样的,都是指向函数调用地址的指针,只是函数名是常量指针,函数指针是变量。

  2. 调用函数的写法func()、(*func)()均可,而我们大多数情况下都会写成前者,应该是(C/C++标准制定者)为了方便大家对函数的调用。 

  博文Function Pointers and Callbacks in C — An Odyssey如此说:

  A pointer is a special kind of variable that holds the address of another variable. The same concept applies to function pointers, except that instead of pointing to variables, they point to functions. If you declare an array, say, int a[10]; then the array name a will in most contexts (in an expression or passed as a function parameter) “decay” to a non-modifiable pointer to its first element (even though pointers and arrays are not equivalent while declaring/defining them, or when used as operands of the sizeof operator). In the same way, for int func();func decays to a non-modifiable pointer to a function. You can think of func as a const pointer for the time being.

void (*pFunc)()与void* pFunc()区别 

  对于前者,我们都知道pFunc是函数指针变量,函数的返回值是空(void)。

  对于后者而言,情况却很不一样。pFunc是函数指针常量,函数的返回值是void指针。

typedef void (*pFunc)()是什么意思?

  发现自己看不懂这个语句了!!!(*pFunc)()是void的别名?这说不通啊!

  typedef的语法如下:

typedef type_declaration;

  为什么自己会看不懂,是因为自己一直把type_declaration分成两个部分,后半部分是前半部分的别名。其实这是错的!!!type_declaration一直是一个整体,而不是分成两半!还得注意,typedef跟#define根本是两回事!

  在下边的语句中,‘void (*pFunc)()’是完整的一个类型声明,也就意味着pFunc不再是一个函数指针变量,而是一个函数指针类型。

typedef void (*pFunc)()

  下边是一个能够说明typedef的简单例子

复制代码

// simple typedef
typedef unsigned long ulong;
 
// the following two objects have the same type
unsigned long l1;
ulong l2;
 
// more complicated typedef
typedef int int_t, *intp_t, (&fp)(int, ulong), arr_t[10];
 
// the following two objects have the same type
int a1[10];
arr_t a2;
 
// common C idiom to avoid having to write "struct S"
typedef struct {int a; int b;} S, *pS;
 
// the following two objects have the same type
pS ps1;
S* ps2;

复制代码

  有了函数指针类型,以后我们就可以象变量一样声明函数指针,如下例:

复制代码

 1 #include <iostream>
 2 using namespace std;
 3 
 4 typedef void(*pFunc)();
 5 
 6 void myFunc()
 7 {
 8     cout << "Hello World!" << endl;
 9 }
10 
11 int main()
12 {
13     pFunc func;
14     func = &myFunc;
15     func();
16     
17     return 0;
18 }

复制代码

回调函数

   回调函数其实就是一个通过函数指针调用的函数!假如你把A函数的指针当作参数传给B函数,然后在B函数中通过A函数传进来的这个指针调用A函数,那么这就是回调机制。A函数就是回调函数,而通常情况下,A函数是系统在符合你设定条件的情况下会自动执行。

  例如Linux下的多线程创建函数

#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
// 返回:若成功返回0,否则返回错误编号

中的 start_rtn 就是一个回调函数。

  下边是一个简易的例子:

复制代码

 1 #include <iostream>
 2 using namespace std;
 3 
 4 typedef void (*callback)(int x);            // 定义一个函数指针类型
 5 
 6 void myFunc1(int x)                         // myFunc1 的声明要与callback一样
 7 {
 8     cout << "This is myFunc1 " << x << endl;
 9 }
10 
11 void myFunc2(int x)
12 {
13     cout << "This is myFunc2 " << x << endl;
14 }
15 
16 void callMyFunc(callback cb, int x)      // 把函数指针类型当做调用函数参数类型
17 {
18     cb(x);
19 }
20 
21 int main()
22 {
23     callMyFunc(myFunc1, 1);
24     callMyFunc(myFunc2, 2);
25 
26     return 0;
27 }

复制代码

  通过这个小程序可以看出,相对于普通函数调用来说,回调函数至少有如下优势:

  把回调函数定义成一个类型并作为调用函数的参数类型,这样只要跟该回调函数类型有相同声明而有不同实现的函数都可以被调用函数调用。这样将极大扩展调用函数的功能。例如,我们可以定义N多个myFunc,而且互相之间实现各不相同,那对于callMyFunc来说就有N种功能。

 

  关于回调函数详细可参考知乎上问答回调函数(callback)是什么?

 

===========================================================================================================================================================================================================================================================================

 

函数对象

有时需要一些行为类似于函数指针的东西。

与智能指针一样,函数对象也是一个普通的类对象

 

智能指针类型重载->和*(可能还有->*)操作符,来模仿指针的行为

 

 

而函数对象类型则重载函数调用操作符(),来创建类似于函数指针的东西

class Fib{

public:

Fib():a0_(1),a1_(1):{}

int operator();

private:

int a0_,a1_;

}

int Fib::operator()

{

int temp = a0_;

a0_ = a1_;

a1_ = temp + a0_;

return temp;

}

函数对象就是常规的类对象,但是可以采用标准的函数调用语法来调用它的opeartor()成员(此成员可以具有多个重载版本)

Fib fib;

//...

cout<<"next two in series" <<fib()<<'  '<<fib()<<endl;

fib()语法被编译器识别为对fib对象的operator()成员函数的调用,这在意思上和fib.operator()等价,但看起来更简洁。

在这个例子中,使用函数对象而不是函数或者函数指针的优势在于,

用于计算菲波那切数列下一个值的状态被存储于Fib对象自身之中

如果采用函数来实现计算功能,那么必须求助于全局或局部静态变量或其他技巧

 

==================================================================================================================================================================================

智能指针是存储指向动态分配(堆)对象指针的类。

=========================================================================================

 

C++11中智能指针的原理、使用、实现

 目录

    • 理解智能指针的原理
    • 智能指针的使用
    • 智能指针的设计和实现

1.智能指针的作用

       C++程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理。程序员自己管理堆内存可以提高了程序的效率,但是整体来说堆内存的管理是麻烦的,C++11中引入了智能指针的概念,方便管理堆内存。使用普通指针,容易造成堆内存泄露(忘记释放),二次释放,程序发生异常时内存泄露等问题等,使用智能指针能更好的管理堆内存。

理解智能指针需要从下面三个层次:

  1. 从较浅的层面看,智能指针是利用了一种叫做RAII(资源获取即初始化)的技术对普通的指针进行封装,这使得智能指针实质是一个对象,行为表现的却像一个指针。
  2. 智能指针的作用是防止忘记调用delete释放内存和程序异常的进入catch块忘记释放内存。另外指针的释放时机也是非常有考究的,多次释放同一个指针会造成程序崩溃,这些都可以通过智能指针来解决。
  3. 智能指针还有一个作用是把值语义转换成引用语义。C++和Java有一处最大的区别在于语义不同,在Java里面下列代码:

  

 

Animal a = new Animal();

  Animal b = a;

     你当然知道,这里其实只生成了一个对象,a和b仅仅是把持对象的引用而已。但在C++中不是这样,

     Animal a;

     Animal b = a;

     这里却是就是生成了两个对象。

   

 

  关于值语言参考这篇文章http://www.cnblogs.com/Solstice/archive/2011/08/16/2141515.html

2.智能指针的使用

智能指针在C++11版本之后提供,包含在头文件<memory>中,shared_ptr、unique_ptr、weak_ptr

2.1 shared_ptr的使用

shared_ptr多个指针指向相同的对象。shared_ptr使用引用计数,每一个shared_ptr的拷贝都指向相同的内存。每使用他一次,内部的引用计数加1,每析构一次,内部的引用计数减1,减为0时,自动删除所指向的堆内存。shared_ptr内部的引用计数是线程安全的,但是对象的读取需要加锁。

  • 初始化。智能指针是个模板类,可以指定类型,传入指针通过构造函数初始化。也可以使用make_shared函数初始化。不能将指针直接赋值给一个智能指针,一个是类,一个是指针。例如std::shared_ptr<int> p4 = new int(1);的写法是错误的
  • 拷贝和赋值。拷贝使得对象的引用计数增加1,赋值使得原对象引用计数减1,当计数为0时,自动释放内存。后来指向的对象引用计数加1,指向后来的对象。
  • get函数获取原始指针
  • 注意不要用一个原始指针初始化多个shared_ptr,否则会造成二次释放同一内存
  • 注意避免循环引用,shared_ptr的一个最大的陷阱是循环引用,循环,循环引用会导致堆内存无法正确释放,导致内存泄漏。循环引用在weak_ptr中介绍。

复制代码

#include <iostream>
#include <memory>

int main() {
    {
        int a = 10;
      

       std::shared_ptr<int> ptra = std::make_shared<int>(a);
        std::shared_ptr<int> ptra2(ptra); //copy


        std::cout << ptra.use_count() << std::endl;

        int b = 20;

        int *pb = &a;
        //std::shared_ptr<int> ptrb = pb;  //error
        std::shared_ptr<int> ptrb = std::make_shared<int>(b);
        ptra2 = ptrb; //assign
        pb = ptrb.get(); //获取原始指针

        std::cout << ptra.use_count() << std::endl;
        std::cout << ptrb.use_count() << std::endl;
    }
}

复制代码

2.2 unique_ptr的使用

  unique_ptr“唯一”拥有其所指对象,同一时刻只能有一个unique_ptr指向给定对象(通过禁止拷贝语义、只有移动语义来实现)。相比与原始指针unique_ptr用于其RAII的特性,使得在出现异常的情况下,动态资源能得到释放。unique_ptr指针本身的生命周期:从unique_ptr指针创建时开始,直到离开作用域。离开作用域时,若其指向对象,则将其所指对象销毁(默认使用delete操作符,用户可指定其他操作)。unique_ptr指针与其所指对象的关系:在智能指针生命周期内,可以改变智能指针所指对象,如创建智能指针时通过构造函数指定、通过reset方法重新指定、通过release方法释放所有权、通过移动语义转移所有权。

复制代码

#include <iostream>
#include <memory>

int main() {
    {
        std::unique_ptr<int> uptr(new int(10));  //绑定动态对象
        //std::unique_ptr<int> uptr2 = uptr;  //不能賦值
        //std::unique_ptr<int> uptr2(uptr);  //不能拷貝
        std::unique_ptr<int> uptr2 = std::move(uptr); //轉換所有權
        uptr2.release(); //释放所有权
    }
    //超過uptr的作用域,內存釋放
}

复制代码

2.3 weak_ptr的使用

  weak_ptr是为了配合shared_ptr而引入的一种智能指针,因为它不具有普通指针的行为,没有重载operator*和->,它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况。weak_ptr可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。使用weak_ptr的成员函数use_count()可以观测资源的引用计数,另一个成员函数expired()的功能等价于use_count()==0,但更快,表示被观测的资源(也就是shared_ptr的管理的资源)已经不复存在。weak_ptr可以使用一个非常重要的成员函数lock()从被观测的shared_ptr获得一个可用的shared_ptr对象, 从而操作资源。但当expired()==true的时候,lock()函数将返回一个存储空指针的shared_ptr。

复制代码

#include <iostream>
#include <memory>

int main() {
    {
        std::shared_ptr<int> sh_ptr = std::make_shared<int>(10);
        std::cout << sh_ptr.use_count() << std::endl;

        std::weak_ptr<int> wp(sh_ptr);
        std::cout << wp.use_count() << std::endl;

        if(!wp.expired()){
            std::shared_ptr<int> sh_ptr2 = wp.lock(); //get another shared_ptr
            *sh_ptr = 100;
            std::cout << wp.use_count() << std::endl;
        }
    }
    //delete memory
}

复制代码

2.4 循环引用

考虑一个简单的对象建模——家长与子女:a Parent has a Child, a Child knowshis/her Parent。在Java 里边很好写,不用担心内存泄漏,也不用担心空悬指针,只要正确初始化myChild 和myParent,那么Java 程序员就不用担心出现访问错误。一个handle 是否有效,只需要判断其是否non null。

public class Parent
{
  private Child myChild;
}
public class Child
{
  private Parent myParent;
}
在C++ 里边就要为资源管理费一番脑筋。如果使用原始指针作为成员,Child和Parent由谁释放?那么如何保证指针的有效性?如何防止出现空悬指针?这些问题是C++面向对象编程麻烦的问题,现在可以借助smart pointer把对象语义(pointer)转变为值(value)语义,shared_ptr轻松解决生命周期的问题,不必担心空悬指针。但是这个模型存在循环引用的问题,注意其中一个指针应该为weak_ptr。

原始指针的做法,容易出错

复制代码

#include <iostream>
#include <memory>

class Child;
class Parent;

class Parent {
private:
    Child* myChild;
public:
    void setChild(Child* ch) {
        this->myChild = ch;
    }

    void doSomething() {
        if (this->myChild) {

        }
    }

    ~Parent() {
        delete myChild;
    }
};

class Child {
private:
    Parent* myParent;
public:
    void setPartent(Parent* p) {
        this->myParent = p;
    }
    void doSomething() {
        if (this->myParent) {

        }
    }
    ~Child() {
        delete myParent;
    }
};

int main() {
    {
        Parent* p = new Parent;
        Child* c =  new Child;
        p->setChild(c);
        c->setPartent(p);
        delete c;  //only delete one
    }
    return 0;
}

复制代码

循环引用内存泄露的问题

复制代码

#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;
    }

    void doSomething() {
        if (this->ChildPtr.use_count()) {

        }
    }

    ~Parent() {
    }
};

class Child {
private:
    std::shared_ptr<Parent> ParentPtr;
public:
    void setPartent(std::shared_ptr<Parent> parent) {
        this->ParentPtr = parent;
    }
    void doSomething() {
        if (this->ParentPtr.use_count()) {

        }
    }
    ~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;
}

复制代码

正确的做法

复制代码

#include <iostream>
#include <memory>

class Child;
class Parent;

class Parent {
private:
    //std::shared_ptr<Child> ChildPtr;
    std::weak_ptr<Child> ChildPtr;
public:
    void setChild(std::shared_ptr<Child> child) {
        this->ChildPtr = child;
    }

    void doSomething() {
        //new shared_ptr
        if (this->ChildPtr.lock()) {

        }
    }

    ~Parent() {
    }
};

class Child {
private:
    std::shared_ptr<Parent> ParentPtr;
public:
    void setPartent(std::shared_ptr<Parent> parent) {
        this->ParentPtr = parent;
    }
    void doSomething() {
        if (this->ParentPtr.use_count()) {

        }
    }
    ~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; // 1
    }
    std::cout << wpp.use_count() << std::endl;  // 0
    std::cout << wpc.use_count() << std::endl;  // 0
    return 0;
}

复制代码

3.智能指针的设计和实现

  下面是一个简单智能指针的demo。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针。每次创建类的新对象时,初始化指针并将引用计数置为1;当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。智能指针就是模拟指针动作的类。所有的智能指针都会重载 -> 和 * 操作符。智能指针还有许多其他功能,比较有用的是自动销毁。这主要是利用栈对象的有限作用域以及临时对象(有限作用域实现)析构函数释放内存。

复制代码

 1 #include <iostream>
 2 #include <memory>
 3 
 4 template<typename T>
 5 class SmartPointer {
 6 private:
 7     T* _ptr;
 8     size_t* _count;
 9 public:
10     SmartPointer(T* ptr = nullptr) :
11             _ptr(ptr) {
12         if (_ptr) {
13             _count = new size_t(1);
14         } else {
15             _count = new size_t(0);
16         }
17     }
18 
19     SmartPointer(const SmartPointer& ptr) {
20         if (this != &ptr) {
21             this->_ptr = ptr._ptr;
22             this->_count = ptr._count;
23             (*this->_count)++;
24         }
25     }
26 
27     SmartPointer& operator=(const SmartPointer& ptr) {
28         if (this->_ptr == ptr._ptr) {
29             return *this;
30         }
31 
32         if (this->_ptr) {
33             (*this->_count)--;
34             if (this->_count == 0) {
35                 delete this->_ptr;
36                 delete this->_count;
37             }
38         }
39 
40         this->_ptr = ptr._ptr;
41         this->_count = ptr._count;
42         (*this->_count)++;
43         return *this;
44     }
45 
46     T& operator*() {
47         assert(this->_ptr == nullptr);
48         return *(this->_ptr);
49 
50     }
51 
52     T* operator->() {
53         assert(this->_ptr == nullptr);
54         return this->_ptr;
55     }
56 
57     ~SmartPointer() {
58         (*this->_count)--;
59         if (*this->_count == 0) {
60             delete this->_ptr;
61             delete this->_count;
62         }
63     }
64 
65     size_t use_count(){
66         return *this->_count;
67     }
68 };
69 
70 int main() {
71     {
72         SmartPointer<int> sp(new int(10));
73         SmartPointer<int> sp2(sp);
74         SmartPointer<int> sp3(new int(20));
75         sp2 = sp3;
76         std::cout << sp.use_count() << std::endl;
77         std::cout << sp3.use_count() << std::endl;
78     }
79     //delete operator
80 }

复制代码

参考:

  1. 值语义:http://www.cnblogs.com/Solstice/archive/2011/08/16/2141515.html
  2. shared_ptr使用:http://www.cnblogs.com/jiayayao/archive/2016/12/03/6128877.html
  3. unique_ptr使用:http://blog.csdn.net/pi9nc/article/details/12227887
  4. weak_ptr的使用:http://blog.csdn.net/mmzsyx/article/details/8090849
  5. weak_ptr解决循环引用的问题:http://blog.csdn.net/shanno/article/details/7363480
  6. C++面试题(四)——智能指针的原理和实现

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值