您的位置:首页 > 编程语言 > C语言/C++

自己实现的C++智能指针的功能代码和测试用例

2016-07-05 00:20 549 查看
1)C++,智能指针的相关知识请 wwww.baidu.com

2)智能指针有很多功能点,不同项目可能需要的智能指针的功能点不一样多,所以人人实现的C++智能指针可能是不一样的。但是:智能指针的最基本的功能点还是必须要遵守的。

3)今天趁着晚上的时间实现了C++ 智能指针的功能代码和测试用例,以下是实现代码。代码经过测试,可能编译通过和测试通过。代码中一定存在缺陷部分,请指出。

4)

注1:对于TRefHelper类中对引用计数器的加减操作,如果是在多线程环境中,就需要使用多线程安全的原子计数器完成引用计数的加减!多线程安全的原子计数器可以参考前面写的文章,"原子计数器 for PThreads",链接:http://blog.csdn.net/u012421852/article/details/51357176

注2:C++中对class进行new操作,不同的入参就会对应调用到class的正确的不同的构造函数,关于new和class构造函数的技术 在 ”只在堆上创建class对象“和”只在栈上创建class对象“会很好的体现,后面会用一篇文件实现new/delete知识点(”只在堆上创建class对象“和”只在栈上创建class对象“)的功能代码和测试用例。

#include <stdio.h>
#include <assert.h>
#include <string>
#include <iostream>
using namespace std;

#define PRINT_FUN_INFO \
do { \
printf("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); \
}while(0);

#define PRINT_REF_INFO \
do { \
printf("%s:%d:%s<objptr, objref>(%p, %d)\n", __FILE__, __LINE__, __FUNCTION__, m_ptr, m_ref);\
}while(0);

class CDog
{
public:
CDog(int age, std::string color):m_age(age), m_color(color)
{
cout<<"Hello one dog<age, color>("<<m_age<<","<<m_color<<")"<<endl;
}
~CDog()
{
cout<<"Bye one dog<age, color>("<<m_age<<","<<m_color<<")"<<endl;
}
void Run()
{
printf("%s:%d:%s, dog(%p).\n", __FILE__, __LINE__, __FUNCTION__);
}
private:
int m_age;
std::string m_color;
};

template<class T> class TRefHelper
{
template<class Y> friend class TSmart_Ptr;
TRefHelper(T *ptr):m_ptr(ptr), m_ref(1)
{
PRINT_REF_INFO;
}
~TRefHelper()
{
PRINT_REF_INFO;
delete m_ptr;
m_ptr = NULL;
}
void delRef()
{
PRINT_REF_INFO;
--m_ref;
}
void addRef()
{
PRINT_REF_INFO;
++m_ref;
}
int getRef() const
{
return m_ref;
}
T* get() const
{
return m_ptr;
}
private:
T* m_ptr;
int m_ref;
};

template<class T> class TSmart_Ptr
{
public:
explicit TSmart_Ptr(T* ptr):m_helper(new TRefHelper<T>(ptr))
{
PRINT_FUN_INFO;
assert (ptr != NULL);
}
explicit TSmart_Ptr(TSmart_Ptr const& other):m_helper(other.m_helper)
{
PRINT_FUN_INFO;
(other.m_helper)->addRef();
}
~TSmart_Ptr()
{
PRINT_FUN_INFO;
m_helper->delRef();
if (m_helper->getRef() == 0)
{
delete m_helper;
m_helper = NULL;
}
}
TSmart_Ptr& operator=(TSmart_Ptr const& rhs)
{
PRINT_FUN_INFO;
if (rhs.get() != get())
{
(rhs.m_helper)->addRef();
(this->m_helper)->delRef();
if ((this->m_helper)->getRef() == 0)
{
delete m_helper;
m_helper = NULL;
}
*this = rhs;
}
return *this;
}
T* get() const
{
PRINT_FUN_INFO;
return m_helper->get();
}
T* operator->() const
{
PRINT_FUN_INFO;
T* ret = NULL;
if (m_helper != NULL)
{
ret = m_helper->get();
}
return ret;
}
T& operator*() const
{
PRINT_FUN_INFO;
T* ret = NULL;
if (m_helper != NULL)
{
ret = m_helper->get();
}
return *ret;
}
bool operator!() const
{
PRINT_FUN_INFO;
assert (m_helper != NULL);
return m_helper->get() != NULL;
}
private:
TRefHelper<T> *m_helper;
};

int main()
{
PRINT_FUN_INFO
CDog *dog = new CDog(25, "Red");
PRINT_FUN_INFO
TSmart_Ptr<CDog> smart_ptr1(dog);
PRINT_FUN_INFO
TSmart_Ptr<CDog> smart_ptr2(smart_ptr1);
PRINT_FUN_INFO
smart_ptr2 = smart_ptr1;
PRINT_FUN_INFO
assert (smart_ptr2.get() != NULL);
PRINT_FUN_INFO
assert (!smart_ptr2);
PRINT_FUN_INFO
smart_ptr2.get()->Run();
PRINT_FUN_INFO
smart_ptr2->Run();
PRINT_FUN_INFO
(*smart_ptr2).Run();
PRINT_FUN_INFO

return 0;
}

可先只进行编译,进行代码调试:
$g++ -c ./SmartPtr.cpp -lstdc++

或者直接编译加链接:

$g++ ./SmartPtr.cpp -lstdc++

下面是运行结果:

./smartptr.cpp:149:main
Hello one dog<age, color>(25,Red)
./smartptr.cpp:151:main
./smartptr.cpp:42:TRefHelper<objptr, objref>(0x8dee020, 1)
./smartptr.cpp:78:TSmart_Ptr
./smartptr.cpp:153:main
./smartptr.cpp:83:TSmart_Ptr
./smartptr.cpp:57:addRef<objptr, objref>(0x8dee020, 1)
./smartptr.cpp:155:main
./smartptr.cpp:98:operator=
./smartptr.cpp:114:get
./smartptr.cpp:114:get
./smartptr.cpp:157:main
./smartptr.cpp:114:get
./smartptr.cpp:159:main
./smartptr.cpp:139:operator!
./smartptr.cpp:161:main
./smartptr.cpp:114:get
./smartptr.cpp:30:Run, dog(0xbfa490e4).
./smartptr.cpp:163:main
./smartptr.cpp:119:operator->
./smartptr.cpp:30:Run, dog(0xbfa490e4).
./smartptr.cpp:165:main
./smartptr.cpp:129:operator*
./smartptr.cpp:30:Run, dog(0xbfa490e4).
./smartptr.cpp:167:main
./smartptr.cpp:88:~TSmart_Ptr
./smartptr.cpp:52:delRef<objptr, objref>(0x8dee020, 2)
./smartptr.cpp:88:~TSmart_Ptr
./smartptr.cpp:52:delRef<objptr, objref>(0x8dee020, 1)
./smartptr.cpp:46:~TRefHelper<objptr, objref>(0x8dee020, 0)
Bye one dog<age, color>(25,Red)

注:为了方便对比测试运行结果和源代码,附录附加上去加了行数的源代码。
1 #include <stdio.h>
2 #include <assert.h>
3 #include <string>
4 #include <iostream>
5 using namespace std;
6
7 #define PRINT_FUN_INFO \
8 do { \
9 printf("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); \
10 }while(0);
11
12 #define PRINT_REF_INFO \
13 do { \
14 printf("%s:%d:%s<objptr, objref>(%p, %d)\n", __FILE__, __LINE__, __FUNCTION__, m_ptr, m_ref);\
15 }while(0);
16
17 class CDog
18 {
19 public:
20 CDog(int age, std::string color):m_age(age), m_color(color)
21 {
22 cout<<"Hello one dog<age, color>("<<m_age<<","<<m_color<<")"<<endl;
23 }
24 ~CDog()
25 {
26 cout<<"Bye one dog<age, color>("<<m_age<<","<<m_color<<")"<<endl;
27 }
28 void Run()
29 {
30 printf("%s:%d:%s, dog(%p).\n", __FILE__, __LINE__, __FUNCTION__);
31 }
32 private:
33 int m_age;
34 std::string m_color;
35 };
36
37 template<class T> class TRefHelper
38 {
39 template<class Y> friend class TSmart_Ptr;
40 TRefHelper(T *ptr):m_ptr(ptr), m_ref(1)
41 {
42 PRINT_REF_INFO;
43 }
44 ~TRefHelper()
45 {
46 PRINT_REF_INFO;
47 delete m_ptr;
48 m_ptr = NULL;
49 }
50 void delRef()
51 {
52 PRINT_REF_INFO;
53 --m_ref;
54 }
55 void addRef()
56 {
57 PRINT_REF_INFO;
58 ++m_ref;
59 }
60 int getRef() const
61 {
62 return m_ref;
63 }
64 T* get() const
65 {
66 return m_ptr;
67 }
68 private:
69 T* m_ptr;
70 int m_ref;
71 };
72
73 template<class T> class TSmart_Ptr
74 {
75 public:
76 explicit TSmart_Ptr(T* ptr):m_helper(new TRefHelper<T>(ptr))
77 {
78 PRINT_FUN_INFO;
79 assert (ptr != NULL);
80 }
81 explicit TSmart_Ptr(TSmart_Ptr const& other):m_helper(other.m_helper)
82 {
83 PRINT_FUN_INFO;
84 (other.m_helper)->addRef();
85 }
86 ~TSmart_Ptr()
87 {
88 PRINT_FUN_INFO;
89 m_helper->delRef();
90 if (m_helper->getRef() == 0)
91 {
92 delete m_helper;
93 m_helper = NULL;
94 }
95 }
96 TSmart_Ptr& operator=(TSmart_Ptr const& rhs)
97 {
98 PRINT_FUN_INFO;
99 if (rhs.get() != get())
100 {
101 (rhs.m_helper)->addRef();
102 (this->m_helper)->delRef();
103 if ((this->m_helper)->getRef() == 0)
104 {
105 delete m_helper;
106 m_helper = NULL;
107 }
108 *this = rhs;
109 }
110 return *this;
111 }
112 T* get() const
113 {
114 PRINT_FUN_INFO;
115 return m_helper->get();
116 }
117 T* operator->() const
118 {
119 PRINT_FUN_INFO;
120 T* ret = NULL;
121 if (m_helper != NULL)
122 {
123 ret = m_helper->get();
124 }
125 return ret;
126 }
127 T& operator*() const
128 {
129 PRINT_FUN_INFO;
130 T* ret = NULL;
131 if (m_helper != NULL)
132 {
133 ret = m_helper->get();
134 }
135 return *ret;
136 }
137 bool operator!() const
138 {
139 PRINT_FUN_INFO;
140 assert (m_helper != NULL);
141 return m_helper->get() != NULL;
142 }
143 private:
144 TRefHelper<T> *m_helper;
145 };
146
147 int main()
148 {
149 PRINT_FUN_INFO
150 CDog *dog = new CDog(25, "Red");
151 PRINT_FUN_INFO
152 TSmart_Ptr<CDog> smart_ptr1(dog);
153 PRINT_FUN_INFO
154 TSmart_Ptr<CDog> smart_ptr2(smart_ptr1);
155 PRINT_FUN_INFO
156 smart_ptr2 = smart_ptr1;
157 PRINT_FUN_INFO
158 assert (smart_ptr2.get() != NULL);
159 PRINT_FUN_INFO
160 assert (!smart_ptr2);
161 PRINT_FUN_INFO
162 smart_ptr2.get()->Run();
163 PRINT_FUN_INFO
164 smart_ptr2->Run();
165 PRINT_FUN_INFO
166 (*smart_ptr2).Run();
167 PRINT_FUN_INFO
168
169 return 0;
170 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: