承接两年前的这篇文章,心里有个梗总放不下。
这是一份old code,是我在更早之前(大概5年前左右)为了学习Android智能指针而做的探索,再不备份可能就面临着遗失的风险。
这份代码比较mini,也比较容易去验证一些特性、学习其内部实现原理。
一些要点说明:
1. 测试手段选择
如果在安卓环境下学习,需要有一份SDK环境和测试机器。这个对许多人想学习的人来说,可能操作起来有点复杂。
PC端模拟器方式可能是一个比较easy的方法,但我本人还没用过。
2. 跨平台化
软件的东西,可复用、跨平台是其优点,因此可以好好利用这个特性。我把安卓的智能指针进行了移植和改造,使其能在PC上比较容易编译和测试。
你只需包含一个头文件“RefBase.h”,并且需要管理的类继承于RefBase即可,例如下面的测试:
1 #define NO_DEBUG 0 2 #define VERBOSE_INFO 0 3 #define WARNING_INFO 1 // when ctor or dtor 4 #define ERROR_INFO 1 5 6 #include <iostream> 7 #include "include/RefBase.h" 8 9 using namespace std; 10 using namespace Rene; 11 12 class tmp : public RefBase 13 { 14 public: 15 tmp() 16 { 17 cout<<"tmp ctor"<<endl; 18 } 19 void printSth(void) 20 { 21 cout<<"hello,world"<<endl; 22 } 23 protected: 24 tmp(const tmp& other) 25 { 26 } 27 tmp(const tmp* other) 28 { 29 } 30 ~tmp() 31 { 32 cout<<"tmp dtor"<<endl; 33 } 34 35 virtual void onFirstRef(void) 36 { 37 cout<<"tmp onFirstRef"<<endl; 38 } 39 }; 40 41 void transfer_sp(sp<tmp> & spt) 42 { 43 sp<tmp> sp_tmp(spt); 44 sp_tmp.printRefs(); 45 } 46 47 void transfer_ptr(tmp * ptr) 48 { 49 sp<tmp> sp_tmp(ptr); 50 sp_tmp.printRefs(); 51 } 52 53 void transfer_obj(sp<tmp> obj) 54 { 55 sp<tmp> sp_tmp(obj); 56 sp_tmp.printRefs(); 57 } 58 59 int main() 60 { 61 tmp *pTmp = new tmp(); 62 cout<<"----------pTmp: "<<pTmp<<"------------"<<endl; 63 sp<tmp> spTmp(pTmp); 64 spTmp.printRefs(); 65 cout<<"----------spTmp: "<<&spTmp<<"------------"<<endl; 66 sp<tmp> sp1Tmp(pTmp); 67 spTmp.printRefs(); 68 spTmp->printSth(); 69 cout<<"----------sp1Tmp: "<<&sp1Tmp<<"------------"<<endl; 70 cout<<"------------ptr------------"<<endl; 71 transfer_ptr(pTmp); 72 cout<<"------------sp ref------------"<<endl; 73 transfer_sp(spTmp); 74 cout<<"------------sp obj------------"<<endl; 75 transfer_obj(spTmp); 76 cout<<"------------print refs------------"<<endl; 77 spTmp.printRefs(); 78 cout<<"------------------------"<<endl; 79 // sp<tmp> sp2Tmp(pTmp); 80 // spTmp.printRefs(); 81 // cout<<"-------------------------------"<<endl; 82 // sp<tmp> sp3Tmp(spTmp); 83 // spTmp.printRefs(); 84 // cout<<"-------------------------------"<<endl; 85 // sp<int> s; 86 // spTmp->printSth(); 87 88 }
3. 该mini code存在哪些问题?
由于具体实现都在.h中,编译时容易引起代码膨胀(预处理阶段,每个.cpp文件都会拷贝一份这个代码,导致生成的.o的size很大,最后bin文件也很大)。
而Android的实现是被编译到libutils.so库中,用只需引用这个(#include <utils/RefBase.h>)即可,生成的bin在运行时只需链接libutils库即可。