C++ 智能指针

释放双眼,带上耳机,听听看~!

1. 智能指针


在c++项目中经常用到指针,new和delete对象成对出现,在大型复杂的项目中肯定也会出现new了对象没有及时delete,导致内存泄露。智能指针的设计理念是用户只管new分配内存,不需要手动去delete,引入引用计数来统计对象的引用次数,当引用计数减到零时来自动delete对象,在android中智能指针大量被使用。

1.1 轻量级智能指针

轻量级智能指针是通过简单的引用计数来维护对象的生命周期。这里我们参考android源码工
程中的framwork智能指针的实现。

  • system/core/include/utils/RefBase.h
  • system/core/include/utils/StrongPointer.h

实现light_smartpoint源码列表

  • RefBase.h
  • StrongPointer.h
  • person.cpp

RefBase.h:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef RS_REF_BASE_H
18#define RS_REF_BASE_H
19
20#include <stdint.h>
21#include <sys/types.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include "StrongPointer.h"
26//#include "TypeHelpers.h"
27using namespace std;
28
29// ---------------------------------------------------------------------------
30namespace android{
31namespace RSC {
32
33
34// ---------------------------------------------------------------------------
35
36template <class T>
37class LightRefBase
38{
39public:
40  inline LightRefBase() : mCount(0) {
41      cout <<"LightRefBase 构造函数 mCount: "<< mCount << " ----++++++++++++-->" << endl;
42  }
43  inline void incStrong(__attribute__((unused)) const void* id) const {
44  __sync_fetch_and_add(&mCount, 1);
45      cout <<"LightRefBase incStrong mCount:"<< mCount << endl  << endl;
46  }
47  inline void decStrong(__attribute__((unused)) const void* id) const {
48      cout <<"LightRefBase before decStrong mCount:"<< mCount << endl;
49      if (__sync_fetch_and_sub(&mCount, 1) == 1) {//mCount为0是返回值为1
50          cout <<"LightRefBase before decStrong mCount:  !!! delete static_cast<const T*>(this) !!! "<< mCount << endl;
51          delete static_cast<const T*>(this);
52      }
53      cout <<"LightRefBase decStrong mCount:"<< mCount << endl;
54  }
55  //! DEBUGGING ONLY: Get current strong ref count.
56  inline int32_t getStrongCount() const {
57      return mCount;
58  }
59
60protected:
61  inline ~LightRefBase() {
62      cout <<"LightRefBase 析构函数 mCount: "<< mCount << " <---++++++++++++--"<< endl;
63  }
64
65private:
66  mutable volatile int32_t mCount;
67};
68
69}; // namespace RSC
70}; // namespace android
71// ---------------------------------------------------------------------------
72
73#endif // RS_REF_BASE_H
74
75
76

StrongPointer.h:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef RS_STRONG_POINTER_H
18#define RS_STRONG_POINTER_H
19
20#include <stdint.h>
21#include <sys/types.h>
22#include <stdlib.h>
23using namespace std;
24
25// ---------------------------------------------------------------------------
26namespace android {
27namespace RSC {
28
29// ---------------------------------------------------------------------------
30
31template <typename T>
32class sp
33{
34public:
35  /* sp 构造函数 */
36  inline sp() : m_ptr(0) {
37      cout <<"sp() : m_ptr(0) 默认构造函数 =====================>"<< endl;
38  }
39  sp(T* other);
40  sp(const sp<T>& other);
41  /* sp 构造函数 end */
42
43  /* 析构函数 */
44  ~sp();
45  /* 析构函数 end*/
46 
47  /* 运算符重载 = * */
48  sp& operator = (T* other);
49  sp& operator = (const sp<T>& other);
50  inline  T&      operator* () const  {
51      cout <<"sp 运算符重载 * "<< endl;
52      return *m_ptr;
53  }
54  inline  T*      operator-> () const {
55      cout <<"sp 运算符重载 -> "<< endl;
56      return m_ptr;
57  }
58  /* 运算符重载 = * end */
59
60private:
61  T* m_ptr;
62};
63
64// ---------------------------------------------------------------------------
65
66template<typename T>
67sp<T>::sp(T* other)
68: m_ptr(other)
69{
70  cout <<" sp<T>::sp(T* other) : m_ptr(other) 构造函数 =====================>"<< endl;
71  if (other) {
72      cout <<" sp<T>::sp(T* other) : m_ptr(other) other->incStrong(this)"<< endl;
73      other->incStrong(this); 
74  }
75     
76}
77
78template<typename T>
79sp<T>::sp(const sp<T>& other)
80: m_ptr(other.m_ptr)
81{
82  cout <<" sp<T>::sp(const sp<T>& other): m_ptr(other.m_ptr) 构造函数 ===============>"<< endl;
83  if (m_ptr) {
84  cout <<" sp<T>::sp(const sp<T>& other): m_ptr(other.m_ptr) m_ptr->incSrong(this)"<< endl;
85  m_ptr->incStrong(this);
86  }
87}
88
89template<typename T>
90sp<T>::~sp()
91{
92  cout << endl << " sp<T>::~sp() 析构函数  <====================="<< endl;
93  if (m_ptr) {
94      cout <<"sp m_ptr->decStrong(this)"<< endl;
95      m_ptr->decStrong(this);
96  }
97}
98
99template<typename T>
100sp<T>& sp<T>::operator = (const sp<T>& other) {
101 T* otherPtr(other.m_ptr);
102 if (otherPtr) otherPtr->incStrong(this);
103 if (m_ptr) m_ptr->decStrong(this);
104 m_ptr = otherPtr;
105 return *this;
106}
107
108template<typename T>
109sp<T>& sp<T>::operator = (T* other)
110{
111 if (other) other->incStrong(this);
112 if (m_ptr) m_ptr->decStrong(this);
113 m_ptr = other;
114 return *this;
115}
116
117}; // namespace RSC
118}; // namespace android
119
120// ---------------------------------------------------------------------------
121
122#endif //
123
124
125

person.cpp:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
1#include <iostream>
2#include <string.h>
3#include <unistd.h>
4#include "RefBase.h"
5
6using namespace std;
7using namespace android::RSC;
8
9class Person : public LightRefBase<Person>{
10
11public:
12  Person() {
13      cout <<"Pserson() ------------>"<< endl;
14  }
15
16  ~Person()
17  {
18      cout << "~Person() <------------"<< endl ;
19  }
20
21  void printInfo(void)
22  {
23      cout<<"just a test function"<<endl;
24  }
25
26};
27
28template<typename T>
29void test_func(sp<T> &other)
30{
31  sp<T> s = other;
32
33  cout<<"In test_func: "<<s->getStrongCount()<<endl;
34
35  s->printInfo();
36 
37}
38
39int main(int argc, char **argv)
40{
41  int i;
42 
43  sp<Person> other = new Person();
44
45  (*other).printInfo();
46  other->printInfo();
47
48  for (i = 0; i < 2; i++)
49  {
50      cout << "++++----------------------test func start------------------------------++++" << endl;
51      cout<<"Before call test_func: "<<other->getStrongCount() << endl;
52      test_func(other);
53      cout<<"After call test_func: "<<other->getStrongCount()<< endl;
54      cout << "++++----------------------test func end  ------------------------------++++" << endl << endl;
55  }
56
57  return 0;
58}
59
60
61

调试结果:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
1$ g++ person.cpp
2$ ./a.out
3LightRefBase 构造函数 mCount: 0 ----++++++++++++-->
4Pserson() ------------>
5 sp<T>::sp(T* other) : m_ptr(other) 构造函数 =====================>
6 sp<T>::sp(T* other) : m_ptr(other) other->incStrong(this)
7LightRefBase incStrong mCount:1
8
9sp 运算符重载 *
10just a test function
11sp 运算符重载 ->
12just a test function
13++++----------------------test func start------------------------------++++
14sp 运算符重载 ->
15Before call test_func: 1
16 sp<T>::sp(const sp<T>& other): m_ptr(other.m_ptr) 构造函数 ===============>
17 sp<T>::sp(const sp<T>& other): m_ptr(other.m_ptr) m_ptr->incSrong(this)
18LightRefBase incStrong mCount:2
19
20sp 运算符重载 ->
21In test_func: 2
22sp 运算符重载 ->
23just a test function
24
25 sp<T>::~sp() 析构函数  <=====================
26sp m_ptr->decStrong(this)
27LightRefBase before decStrong mCount:2
28LightRefBase decStrong mCount:1
29sp 运算符重载 ->
30After call test_func: 1
31++++----------------------test func end  ------------------------------++++
32
33++++----------------------test func start------------------------------++++
34sp 运算符重载 ->
35Before call test_func: 1
36 sp<T>::sp(const sp<T>& other): m_ptr(other.m_ptr) 构造函数 ===============>
37 sp<T>::sp(const sp<T>& other): m_ptr(other.m_ptr) m_ptr->incSrong(this)
38LightRefBase incStrong mCount:2
39
40sp 运算符重载 ->
41In test_func: 2
42sp 运算符重载 ->
43just a test function
44
45 sp<T>::~sp() 析构函数  <=====================
46sp m_ptr->decStrong(this)
47LightRefBase before decStrong mCount:2
48LightRefBase decStrong mCount:1
49sp 运算符重载 ->
50After call test_func: 1
51++++----------------------test func end  ------------------------------++++
52
53
54 sp<T>::~sp() 析构函数  <=====================
55sp m_ptr->decStrong(this)
56LightRefBase before decStrong mCount:1
57LightRefBase before decStrong mCount:  !!! delete static_cast<const T*>(this) !!! 0
58~Person() <------------
59LightRefBase 析构函数 mCount: 0 <---++++++++++++--
60LightRefBase decStrong mCount:0
61
62
63

uml关系图

C++ 智能指针

1.2 弱指针wp和强指针sp

1.2.1 轻量级智能指针存在的问题

在这样的场景下:父对象father指向子对象son,然后子对象又指向父对象,就存在了循环
引用的现象。将上面person.cpp 修改如下:

person.cpp


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
1#include <iostream>
2#include <string.h>
3#include <unistd.h>
4#include "RefBase.h"
5
6using namespace std;
7using namespace android::RSC;
8
9class Person : public LightRefBase<Person>{
10
11private:
12  sp<Person> father;
13  sp<Person> son;
14
15public:
16  Person() {
17      cout <<"Pserson() ------------>"<< endl;
18  }
19
20  ~Person()
21  {
22      cout << "~Person() <------------"<< endl ;
23  }
24
25  void setFather(sp<Person> &father)
26  {
27      this->father = father;
28  }
29
30  void setSon(sp<Person> &son)
31  {
32      this->son = son;
33  }
34  void printInfo(void)
35  {
36      cout<<"just a test function"<<endl;
37  }
38
39};
40
41void test_func()
42{
43  /* 1. 对于 new Person()
44   * 1.1 先构造父类LightRefBase对象
45   * 1.2 Person对象里的father先被构造
46   * 1.3 Person对象里的son被构造
47   * 1.4 Person对象本身
48   * 2. Person对象的指针传给"sp<Person> father"
49   *    导致: sp(T* other) 被调用
50   *    它增加了这个Person对象的引用计数(现在此值等于1)
51   */
52  sp<Person> father = new Person();
53
54
55  /* 1. 对于 new Person()
56   * 1.1 先构造父类LightRefBase对象
57   * 1.2 Person对象里的father先被构造
58   * 1.3 Person对象里的son被构造
59   * 1.4 Person对象本身
60   * 2. Person对象的指针传给"sp<Person> son"
61   *    导致: sp(T* other) 被调用
62   *    它增加了这个Person对象的引用计数(现在此值等于1)
63   */
64  sp<Person> son = new Person();
65
66  /* 它是一个"=" : this->son = son
67   * "="被重载, 它会再次增加该Person对象的引用计数
68   * 所以son对应的Person对象的引用计数增加为2
69   */
70  father->setSon(son);
71
72  /* 它是一个"=" : this->father = father
73   * "="被重载, 它会再次增加该Person对象的引用计数
74   * 所以father对应的Person对象的引用计数增加为2
75   */
76  son->setFather(father);
77
78
79  /* 当test_func执行完时, father和son被析构
80   * 1. 先看father:
81   *    ~sp(): decStrong, 里面会将计数值减1 , father对应的Person的计数值等于1, 还没等于0, 所以没有delete
82   * 2. 对于son:
83   *    ~sp(): decStrong, 里面会将计数值减1 , son对应的Person的计数值等于1, 还没等于0, 所以没有delete
84   */
85}
86
87int main(int argc, char **argv)
88{
89  int i;
90#if 0
91  sp<Person> other = new Person();
92
93  (*other).printInfo();
94  other->printInfo();
95
96  for (i = 0; i < 2; i++)
97  {
98      cout << "++++----------------------test func start------------------------------++++" << endl;
99      cout<<"Before call test_func: "<<other->getStrongCount() << endl;
100     test_func(other);
101     cout<<"After call test_func: "<<other->getStrongCount()<< endl;
102     cout << "++++----------------------test func end  ------------------------------++++" << endl << endl;
103 }
104#endif
105 /* 先构造父类LightRefBase对象,其次是类中其他对象成员sp<Person>, 再构造对象本身 Person */
106 test_func();
107 return 0;
108}
109
110
111

调试结果:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
1$ g++ person.cpp
2$ ./a.out
3LightRefBase 构造函数 mCount: 0 ----++++++++++++-->
4sp() : m_ptr(0) 默认构造函数 =====================>
5sp() : m_ptr(0) 默认构造函数 =====================>
6Pserson() ------------>
7 sp<T>::sp(T* other) : m_ptr(other) 构造函数 =====================>
8 sp<T>::sp(T* other) : m_ptr(other) other->incStrong(this)
9LightRefBase incStrong mCount:1
10
11LightRefBase 构造函数 mCount: 0 ----++++++++++++-->
12sp() : m_ptr(0) 默认构造函数 =====================>
13sp() : m_ptr(0) 默认构造函数 =====================>
14Pserson() ------------>
15 sp<T>::sp(T* other) : m_ptr(other) 构造函数 =====================>
16 sp<T>::sp(T* other) : m_ptr(other) other->incStrong(this)
17LightRefBase incStrong mCount:1
18
19sp 运算符重载 ->
20LightRefBase incStrong mCount:2
21
22sp 运算符重载 ->
23LightRefBase incStrong mCount:2
24
25
26 sp<T>::~sp() 析构函数  <=====================
27sp m_ptr->decStrong(this)
28LightRefBase before decStrong mCount:2
29LightRefBase decStrong mCount:1
30
31 sp<T>::~sp() 析构函数  <=====================
32sp m_ptr->decStrong(this)
33LightRefBase before decStrong mCount:2
34LightRefBase decStrong mCount:1
35
36
37

通过调试结果我们可以看到,父对象和子对象的引用计数还未减到0,还存在内存泄露。父
对象指向了子对象,所以子对象的引用计数不为0,同样,子对象指向了父对象,父对象的
引用计数不为0,导致两个对象都为被需要的状态,不能释放,导致恶性循环。

1.2.2 弱指针的引入和强指针

解决上述矛盾的一种有效方法是采用弱引用,针对上面父对象使用强指针来引用子对象,而子对象只使用弱引用来指向父对象,双方规定当强引用计数为0时,不论弱引用是否为0都可delete自己(在Android中这个规则可调整)这样只有一方得到了释放,就可以成功避免死锁,但有可能出现野指针情况,如父对象因为强指针引用计数为0,生命周期结束。
但此时子类还持有父类的弱引用,显然子类的这个指针访问父类将引发致命的问题,因此特别规定:弱指针必须先升级为强指针,才能访问它所指向的目标对象。

强指针和弱指针是通过强引用计数和弱引用计数来维护对象的生命周期。一个类的对象要支持使用强指针和弱指针,就必须从RefBase类继承下来,因为RefBase类提供了强引用计数器和弱引用计数器,强指针和弱指针关系密切,配合在一起使用。

RefBase类和LightBase类一样,也提供了成员函数incStrong和decStrong来维护它所引用的对象的引用计数。区别在于它不是直接使用一个整数来维护对象的引用计数的,而是使用一个weakref_impl对象,即成员变量mRefs来描述对象的引用计数。weakref_impl类同时为对象提供了强引用计数和弱引用计数,这里不展开讲解,实现还是比较复杂,目前主要还是先明白怎样使用起来,深入理解可参考《Android系统源代码情景分析》和Android源码。

弱指针的主要使命是解决循环引用的问题。对上面的程序改进如下:

代码列表:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
1$:~/cpp/weakpointer$ tree
2├── include
3│   ├── cutils                     [system/core/include/cutils]
4│   │   ├── atomic.h
5│   │   └── atomic-x86_64.h
6│   └── utils                  [system/core/include/utils]
7│       ├── RefBase.h
8│       ├── StrongPointer.h
9│       └── TypeHelpers.h
10├── Makefile
11├── person.cpp
12└── RefBase.cpp                 [system/core/include/libutils]
13
14

person.cpp


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
1#include <iostream>
2#include <string.h>
3#include <unistd.h>
4#include <utils/RefBase.h>
5
6using namespace std;
7using namespace android;
8
9class Person : public RefBase{
10
11private:
12  char *name;
13  sp<Person> father;
14  //sp<Person> son;
15  wp<Person> son;
16
17public:
18  Person() {
19      cout <<"Person() ------------>"<< endl;
20  }
21
22  Person(char *name) {
23      cout <<"Person(char *name)"<<endl;
24      this->name = name;
25  }
26  ~Person()
27  {
28      cout << "~Person() <------------"<< endl ;
29  }
30
31  void setFather(sp<Person> &father)
32  {
33      this->father = father;
34  }
35
36  void setSon(sp<Person> &son)
37  {
38      this->son = son;
39  }
40  char *getName(void)
41  {
42      return name;
43  }
44  void printInfo(void)
45  {
46      sp<Person> f = father;
47      //sp<Person> s = son;
48      /* 弱指针必须先升级为强指针,才能访问它所指向的目标对象 */
49      sp<Person> s = son.promote();
50      //cout<<"just a test function"<<endl;
51      cout<<"I am "<<name<<endl;
52      if (f != 0)
53          cout<<" My Father is "<<f->getName()<<endl;
54      if (s != 0)
55          cout<<" My Son is "<<s->getName()<<endl;
56  }
57
58};
59
60void test_func()
61{
62  /* 1. 对于 new Person()
63   * 1.1 先构造父类LightRefBase对象
64   * 1.2 Person对象里的father先被构造
65   * 1.3 Person对象里的son被构造
66   * 1.4 Person对象本身
67   * 2. Person对象的指针传给"sp<Person> father"
68   *    导致: sp(T* other) 被调用
69   *    它增加了这个Person对象的引用计数(现在此值等于1)
70   */
71  sp<Person> father = new Person("LiShi");
72
73
74  /* 1. 对于 new Person()
75   * 1.1 先构造父类LightRefBase对象
76   * 1.2 Person对象里的father先被构造
77   * 1.3 Person对象里的son被构造
78   * 1.4 Person对象本身
79   * 2. Person对象的指针传给"sp<Person> son"
80   *    导致: sp(T* other) 被调用
81   *    它增加了这个Person对象的引用计数(现在此值等于1)
82   */
83  sp<Person> son = new Person("LiHua");
84
85  /* 它是一个"=" : this->son = son
86   * "="被重载, 它会再次增加该Person对象的引用计数
87   * 所以son对应的Person对象的引用计数增加为2
88   */
89  father->setSon(son);
90
91  /* 它是一个"=" : this->father = father
92   * "="被重载, 它会再次增加该Person对象的引用计数
93   * 所以father对应的Person对象的引用计数增加为2
94   */
95  son->setFather(father);
96
97  father->printInfo();
98
99  son->printInfo();
100 /* 当test_func执行完时, father和son被析构
101  * 1. 先看father:
102  *    ~sp(): decStrong, 里面会将计数值减1 , father对应的Person的计数值等于1, 还没等于0, 所以没有delete
103  * 2. 对于son:
104  *    ~sp(): decStrong, 里面会将计数值减1 , son对应的Person的计数值等于1, 还没等于0, 所以没有delete
105  */
106}
107
108int main(int argc, char **argv)
109{
110 int i;
111#if 0
112 sp<Person> other = new Person();
113
114 (*other).printInfo();
115 other->printInfo();
116
117 for (i = 0; i < 2; i++)
118 {
119     cout << "++++----------------------test func start------------------------------++++" << endl;
120     cout<<"Before call test_func: "<<other->getStrongCount() << endl;
121     test_func(other);
122     cout<<"After call test_func: "<<other->getStrongCount()<< endl;
123     cout << "++++----------------------test func end  ------------------------------++++" << endl << endl;
124 }
125#endif
126 /* 先构造父类LightRefBase对象,其次是类中其他对象成员sp<Person>, 再构造对象本身 Person */
127 test_func();
128
129 wp<Person> s = new Person("zhangsan");
130 /*
131  * person.cpp:109:3: error: base operand of ‘->’ has non-pointer type ‘android::wp<Person>’
132  * person.cpp:110:3: error: no match for ‘operator*’ (operand type is ‘android::wp<Person>’)
133 */
134 //s->printInfo(); /* 出错, wp没有重载"->", "*" */
135 //(*s).printInfo(); /* 出错, wp没有重载"->", "*" */
136
137 /* 弱指针必须先升级为强指针,才能访问它所指向的目标对象 */
138 sp<Person> s2 = s.promote();
139 if (s2 != 0) {
140     s2->printInfo();
141 }
142
143 return 0;
144}
145
146
147

调试结果:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1$ ./person
2Person(char *name)
3Person(char *name)
4I am LiShi
5 My Son is LiHua
6I am LiHua
7 My Father is LiShi
8~Person() <------------
9~Person() <------------
10Person(char *name)
11I am zhangsan
12~Person() <------------
13
14
15

给TA打赏
共{{data.count}}人
人已打赏
安全技术

详解Node.js API系列 Http模块(2) CNodejs爬虫实现

2021-12-21 16:36:11

安全技术

从零搭建自己的SpringBoot后台框架(二十三)

2022-1-12 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索