《C++新经典设计模式》之附录B 引用技术基础理论和实践
引用技术.cpp
#include <iostream>
#include <memory>
#include <string>
#include <cstring>
using namespace std;
namespace B_1_1
{
void func()
{
shared_ptr<int> myp(new int(5));
int icount = myp.use_count();
cout << "icount = " << icount << endl;
{
shared_ptr<int> myp2(myp);
icount = myp2.use_count();
cout << "icount = " << icount << endl;
}
icount = myp.use_count();
cout << "icount = " << icount << endl;
}
}
// string典型实现方式:
// eager-copy(贪婪的/粗暴的拷贝)、copy-on-write(写时复制,fork()子进程,引用计数)、small string optimization(短字符串优化)
namespace B_1_2
{
void func()
{
string str1 = "I Love China!";
string str2 = str1;
cout << "str1 address: " << static_cast<const void *>(str1.c_str()) << endl;
cout << "str2 address: " << static_cast<const void *>(str2.c_str()) << endl;
}
}
namespace B_2_1
{
class mystring
{
char *point; // 指向实际的字符串
public:
mystring(const char *tmpstr = "") // 构造函数
{
point = new char[strlen(tmpstr) + 1]; // 给字符串末尾的\0留位置。
strcpy(point, tmpstr);
cout << "1" << endl;
}
~mystring()
{
delete[] point;
}
mystring(const mystring &tmpstr) // 拷贝构造函数
{
point = new char[strlen(tmpstr.point) + 1];
strcpy(point, tmpstr.point);
cout << "2" << endl;
}
mystring &operator=(const mystring &tmpstr) // 拷贝赋值运算符
{
if (this == &tmpstr)
return *this;
delete[] point;
point = new char[strlen(tmpstr.point) + 1];
strcpy(point, tmpstr.point);
cout << "3" << endl;
return *this;
}
};
}
namespace B_2_2345
{
class mystring
{
struct stringvalue
{
size_t refcount; // 引用计数
char *point; // 指向实际字符串
stringvalue(const char *tmpstr = "") : refcount(1) // stringvalue构造函数
{
point = new char[strlen(tmpstr) + 1];
strcpy(point, tmpstr);
}
~stringvalue()
{
delete[] point;
}
};
stringvalue *pvalue; // mystring类中指向stringvalue对象的指针
public:
mystring(const char *tmpstr = "") : pvalue(new stringvalue(tmpstr)) {} // 构造函数
mystring(const mystring &tmpstr) : pvalue(tmpstr.pvalue) // 拷贝构造函数
{
++pvalue->refcount;
}
mystring &operator=(const mystring &tmpstr) // 拷贝赋值运算符
{
if (this == &tmpstr)
return *this;
--pvalue->refcount;
if (pvalue->refcount == 0)
delete pvalue;
pvalue = tmpstr.pvalue;
++pvalue->refcount;
return *this;
}
~mystring()
{
--pvalue->refcount;
if (pvalue->refcount == 0)
delete pvalue;
}
};
}
// 外部加锁:调用者决定跨线程使用共享对象时的加锁时机
// 内部加锁:对象访问串行化,每个成员函数加锁(不常见)
namespace B_2_6
{
class mystring
{
struct stringvalue
{
size_t refcount; // 引用计数
char *point; // 指向实际字符串
stringvalue(const char *tmpstr = "") : refcount(1) // stringvalue构造函数
{
point = new char[strlen(tmpstr) + 1];
strcpy(point, tmpstr);
}
~stringvalue()
{
delete[] point;
}
};
stringvalue *pvalue; // mystring类中指向stringvalue对象的指针
public:
mystring(const char *tmpstr = "") : pvalue(new stringvalue(tmpstr)) {} // 构造函数
mystring(const mystring &tmpstr) : pvalue(tmpstr.pvalue) // 拷贝构造函数
{
++pvalue->refcount;
}
mystring &operator=(const mystring &tmpstr) // 拷贝赋值运算符
{
if (this == &tmpstr)
return *this;
--pvalue->refcount;
if (pvalue->refcount == 0)
delete pvalue;
pvalue = tmpstr.pvalue;
++pvalue->refcount;
return *this;
}
~mystring()
{
--pvalue->refcount;
if (pvalue->refcount == 0)
delete pvalue;
}
public:
// 存在非const[]版本时,const[]版本已失效
// const char &operator[](int idx) const { return pvalue->point[idx]; }
char &operator[](int idx)
{
if (pvalue->refcount > 1) // 两个及以上对象指向这个字符串
{
--pvalue->refcount;
pvalue = new stringvalue(pvalue->point); // 写时复制
}
return pvalue->point[idx];
}
};
}
namespace B_2_7
{
class mystring
{
struct stringvalue
{
size_t refcount; // 引用计数
char *point;
bool shareable; // 指向实际字符串
stringvalue(const char *tmpstr = "") : refcount(1), shareable(true) // stringvalue构造函数
{
point = new char[strlen(tmpstr) + 1];
strcpy(point, tmpstr);
}
~stringvalue()
{
delete[] point;
}
};
stringvalue *pvalue; // mystring类中指向stringvalue对象的指针
public:
mystring(const char *tmpstr = "") : pvalue(new stringvalue(tmpstr)) {} // 构造函数
mystring(const mystring &tmpstr) // 拷贝构造函数
{
if (tmpstr.pvalue->shareable)
{
pvalue = tmpstr.pvalue;
++pvalue->refcount;
}
else
{
pvalue = new stringvalue(tmpstr.pvalue->point);
}
}
mystring &operator=(const mystring &tmpstr) // 拷贝赋值运算符
{
if (this == &tmpstr)
return *this;
--pvalue->refcount;
if (pvalue->refcount == 0)
delete pvalue;
pvalue = tmpstr.pvalue;
++pvalue->refcount;
return *this;
}
~mystring()
{
--pvalue->refcount;
if (pvalue->refcount == 0)
delete pvalue;
}
public:
// 存在非const[]版本时,const[]版本已失效
// const char &operator[](int idx) const { return pvalue->point[idx]; }
char &operator[](int idx)
{
if (pvalue->refcount > 1) // 两个及以上对象指向这个字符串
{
--pvalue->refcount;
pvalue = new stringvalue(pvalue->point); // 写时复制
}
pvalue->shareable = false; // 调用operator[]后,字符串无法共享
return pvalue->point[idx];
}
};
}
int main()
{
#if 0
B_1_1::func();
#endif
#if 0
B_1_2::func();
#endif
#if 0
using namespace B_2_1;
mystring kxstr1("I Love China!"); // 构造函数
mystring kxstr2 = "I Love China!"; // 构造函数
mystring kxstr3 = kxstr1; // 拷贝构造函数
kxstr2 = kxstr1; // 拷贝赋值运算符
#endif
#if 0
using namespace B_2_2345;
mystring kxstr1("I Love China!"); // 构造函数
mystring kxstr2("I Love China!"); // 构造函数
mystring kxstr3 = kxstr1; // 拷贝构造函数
#endif
#if 0
using namespace B_2_6;
mystring ms = "I Love China!";
cout << ms[0] << endl;
ms[0] = 'Y';
cout << ms[0] << endl;
#endif
#if 1
using namespace B_2_7;
mystring kxstr4 = "I Love China!";
char *mypoint = &kxstr4[0];
mystring kxstr5 = kxstr4;
*mypoint = 'Y';
cout << kxstr4[0] << endl;
cout << kxstr5[0] << endl;
#endif
cout << "Over!\n";
return 0;
}