前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用C++实现一个简易的golang 的Slice

用C++实现一个简易的golang 的Slice

作者头像
我不是码神
发布2022-07-28 14:32:32
2000
发布2022-07-28 14:32:32
举报
文章被收录于专栏:流媒体技术

废话不说,直接上代码

代码语言:javascript
复制
struct Slice
{
	SharedStr* sharedStr;
	int p;
	int length;
	virtual ~Slice()
	{
		sharedStr->free();
	}
	Slice():Slice("") {

	}
	Slice(const Slice& right) : p(right.p),length(right.length)
	{
		right.sharedStr->copy(&sharedStr);
	}
	Slice& operator=(const Slice& right)  {
		right.sharedStr->copy(&sharedStr);
		p = right.p;
		length = right.length;
		return *this;
	}
	Slice(string&& data):p(0)
	{
		length = data.length();
		sharedStr = new SharedStr(move(data));
	}
	Slice(Slice* parent, int start, int end)
	{
		parent->sharedStr->copy(&sharedStr);
		p = parent->p + start;
		length = end - start;
	}
	Slice(int len, int cap) : length(len),p(0)
	{
		if (!cap)cap = len;
		sharedStr = new SharedStr(cap);
	}
	size_t cap() {
		return sharedStr->capacity() - p;
	}
	Slice operator()(int start, int end)
	{
		return Slice(this, start, end);
	}
	unsigned char operator[](int i)
	{
		return ((unsigned char*)(*sharedStr))[p+i];
	}
	Slice operator+(const Slice& right) {
		return append((void*)right.point(), right.length);
	}
	const char* point() const{
		return sharedStr->data.data() + p;
	}
	Slice append(void * data ,int len) {
		if (len > cap() - length) {
			string newStr;
			newStr.resize(p + length + len);
			memcpy((void*)newStr.data(), sharedStr->data.data(), p + length);
			memcpy((void*)(newStr.data() + p + length), data, len);
			return Slice(move(newStr));
		}
		memcpy((void*)(point() + length), data, len);
		return Slice(this, 0, length + len);
	}
	OPERATOR_CHARS((*sharedStr)+p)
};

由于C++的下标运算符的重写没办法实现和golang一致的语法,所以只能退而求其次,使用括号运算符代替。

数据存放在一个SharedStr的结构体中,该结构体在多个Slice对象中共享,这个思路是取自C++的智能指针的设计原理。

实现了移动构造函数以提高性能

SharedStr的代码如下

代码语言:javascript
复制
struct SharedStr
{
    string data;
    int refCount;
	SharedStr(size_t size):refCount(1) {
		data.reserve(size);
	}
    SharedStr(string &&right) : data(move(right)),refCount(1)
    {
    }
    
    void free()
    {
        refCount--;
        if (refCount == 0)
        {
            delete this;
        }
    }
	void copy(SharedStr** target) {
		*target = this;
		refCount++;
	}
	void expend(size_t t) {
		data.resize(data.capacity() + t);
	}
	size_t capacity() {
		return data.capacity();
	}
	OPERATOR_CHARS(data.data())
};

OPERATOR_CHARS宏不用管,是各种类型转换

每当Slice被析构的时候,都会使得共享数据引用计数减一,反之被复制就加一,达到0的时候就释放共享数据。

共享数据采用string类型存储,string类型本身实现了长度和容量等功能,可以直接使用。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-09-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档