shared_ptr的子数据(类似于?的子字符串)
Subdata (substring-like?) of a shared_ptr
我在shared_ptr<void>
中存储了一个数据缓冲区。
这个缓冲区被组织在几个封装层中,所以我最终得到了:
-----------------------------------...
- Header 1 | Header 2 | Data
-----------------------------------...
(实际上,这是一个以太网数据包,我在其中一个接一个地解封装层)。
一旦我读取了Header 1,我想将数据包的其余部分传递到下一层进行读取,所以我想创建一个指向的指针
-----------------------...
- Header 2 | Data
-----------------------...
使用原始指针会非常容易,因为这只是指针算术的问题。但是,我如何使用shared_ptr来实现这一点呢?(我使用boost::shared_ptr):
- 我无法创建一个新的shared_ptr到"first shared_ptr.get()+offset",因为只将所有权分配给
Header 2 + Data
是没有意义的(删除最终会崩溃) - 我不想复制这些数据,因为那样会很傻
- 我希望整个缓冲区的所有权在两个对象之间共享(即,只要父对象或只需要Header 2的对象需要数据,就不应该删除数据)
我可以用boost::tuple<shared_ptr<void>, int /*offset*/, int /*length*/>
这样的结构来封装它,但我想知道是否有更方便/更优雅的方法来实现这个结果。
谢谢,
我建议将每个层封装在一个类中,该类知道如何处理数据,就好像它是那个层一样。将每一个视为进入缓冲区的视图。这是一个让你思考的起点。
class Layer1{
public:
Layer1(shared_ptr<void> buffer) : buffer_(buffer) { }
/* All the functions you need for treating your buffer as a Layer 1 type */
void DoSomething() {}
private:
shared_ptr<void> buffer_;
};
class Layer2{
public:
Layer2(shared_ptr<void> buffer) : buffer_(buffer) { }
/* All the functions you need for treating your buffer as a Layer 2 type */
void DoSomethingElse() {}
private:
shared_ptr<void> buffer_;
};
以及如何使用:
shared_ptr<void> buff = getBuff(); //< Do what you need to get the raw buffer.
// I show these together, but chances are, sections of your code will only need
// to think about the data as though it belongs to one layer or the other.
Layer1 l1(buff);
Layer2 l2(buff);
l1.DoSomething();
l2.DoSomethingElse();
通过这种方式进行布局,您可以编写仅在该层上操作的函数,即使它们在内部表示相同的数据。
但是,这绝非完美
也许Layer2应该能够调用Layer1的方法。为此,您也希望继承。我对你的设计了解不多,不知道那是否有用。另一个需要改进的地方是用一个具有处理缓冲区的有用方法的类来替换shared_ptr<void>
。
你能用一个简单的包装器吗?
也许是这样的?
class HeaderHolder : protected shared_ptr<void> {
public:
// Constructor and blah blah
void* operator* () {
offset += a_certain_length;
return (shared_ptr<void>::operator*() + offset);
}
};
顺便说一句,我只是使用了一个简单的包装器,如果有人在这个问题上出错,我会在这里复制它。
class DataWrapper {
public:
DataWrapper (shared_ptr<void> pData, size_t offset, size_t length) : mpData(pData), mOffset(offset), mLength(length) {}
void* GetData() {return (unsigned char*)mpData.get() + mOffset;}
// same with const...
void SkipData (size_t skipSize) { mOffset += skipSize; mLength -= skipSize; }
void GetLength const {return mLength;}
// Then you can add operator+, +=, (void*), -, -=
// if you need pointer-like semantics.
// Also a "memcpy" member function to copy just this buffer may be useful
// and other helper functions if you need
private:
shared_ptr<void> mpData;
size_t mOffset, mLength;
};
使用GetData时要小心:确保在使用不安全的void*时不会释放缓冲区。只要您知道DataWrapper对象是活动的,就可以安全地使用void*(因为它在缓冲区中保存了一个shared_ptr,所以它可以防止它被释放)。
- 类似于strcat()的函数出现问题
- 如何将C++闭包与变量参数同时重用——类似于JavaScript
- 算术运算的结果类似于:C浮点变量中的1/3
- 在数组中输入 n 个整数的列表,并以类似于钟摆来回移动的方式排列它们. 输入-1 3 2 5 4,输出5 3 1 2 4
- 创建类似于布尔值的变量类型
- 如何在 Arduino 字符串的开头添加元素.类似于 JS unshift();
- Java 中是否有类似于 C++ 中引用类型"&"的内容?
- C++未知长度字符串的数组,其行为类似于 Python 字符串列表
- 构造一个类似于JSON文件c++的字符串
- C# 是否有办法将双精度数组强制转换为类似于C++转换为 char* 的字符串?
- shared_ptr的子数据(类似于?的子字符串)
- search用字符串列表输入数字(类似于t9字典)
- 如何传递字符串或类似于结构或对象名称的东西
- 创建行为类似于字符串流的类的最简单方法
- 将字符串的向量连接到std::ostream(类似于boost::Join)
- 在C++中创建原始文本字符串,类似于 C# 的"@ string"
- 为什么std::字符串串联运算符的工作原理类似于右关联运算符
- 如何检查_bstr_t是否包含字符串(类似于str.find)
- 基于特定分隔符拆分字符串的最有效的c++方法是什么?类似于python中的split方法
- 比较两个字符串(类似于GNUdiff的操作)