0
点赞
收藏
分享

微信扫一扫

【ArcGIS Pro二次开发】(78):批量合并GDB数据库

嚯霍嚯 2023-12-05 阅读 15

《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;
}
举报

相关推荐

0 条评论