指向智能指针托管数组中的智能指针



我正在围绕一个存储在字符数组中的低级对象编写一个C++包装器。我希望能够使用智能指针来管理我的类的生命周期。我的类中有几个成员需要返回指向对象的指针;由于这些不是单独的分配,我不能为它们使用标准的智能指针,并且一旦释放主对象,这些指针将变得无效。

对于具体性,考虑以下简单的字符串类:

class 
String
{
char* s;
size_t len;
protected:
String(const char* str) {
len = std::strlen(str);
s = new char[len];
std::strcpy(s, str);
}
public:
~String() {
delete s;
}
char*
getString() {
return s;
}
char*
getSubstr(size_t idx) {
if (idx < len)
return &s[idx];
else
return nullptr;
}
static std::shared_ptr<String>
makeString(const char* str) {
return std::shared_ptr<String>(new String(str));
}
};

我可以使用std::shared_ptr来管理String的实例。但是当我的String对象被破坏时,getString()getSubstring()返回的任何指针都将无效。我希望有一种方法让getString()getSubstring()返回某种智能指针,该指针将保存对父对象的引用,因此以下代码有效:

std::shared_ptr<String> str = String::makeString("Hello world");
SOMETHING<char> substr = str->getSubstr(6);
std::printf("String: %sn", str->getString());
str.reset();
std::printf("Substring: %sn", substr.get());

有没有任何方法可以使用标准C++功能来实现这一点?如果没有,Boost怎么办?

更新

以下是一个似乎有效的版本(当使用gcc或clang编译为C++11时),基于Yakk的建议:

#include <cstring>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
using boost::shared_ptr;
using boost::enable_shared_from_this;
class 
String : public enable_shared_from_this<String>
{
size_t len;
char* s;
protected:
String(const char* str) : len(std::strlen(str)), s(new char[len]) {
std::copy(str, str+len, s);
}
public:
~String() {
delete s;
}
shared_ptr<char[]>
getString() {
return shared_ptr<char[]>(shared_from_this(), s);
}
shared_ptr<char[]>
getSubstr(size_t idx) {
if (idx < len)
return shared_ptr<char[]>(shared_from_this(), s+idx);
else
return shared_ptr<char[]>();
}
static shared_ptr<String>
makeString(const char* str) {
return shared_ptr<String>(new String(str));
}
};

您可能想要shared_ptr"别名"构造函数。

如果您支持C++1z,您甚至可以获得[]

你的"SOMETHING"只是shared_ptr

std::shared_ptr<char>
getSubstr(size_t idx) {
if (idx < len)
return {shared_from_this(), &s[idx]};
else
return {};
}

并将CCD_ 11添加到CCD_。

或者,通过String:内的shared_ptr直接管理缓冲区

std::shared_ptr<char> s;

String(const char* str) {
len = std::strlen(str);
s = std::shared_ptr<char>(new char[len], std::default_deleter<char[]>{});
std::strcpy(s.get(), str);
}
std::shared_ptr<char>
getSubstr(size_t idx) {
if (idx < len)
return {s, s.get()+idx};
else
return {};
}

这种策略的优点是String不需要由共享ptr管理——您可以将其粘贴在向量中或在堆栈上声明。C++在这样的正则类型上非常流行。

同时,内部缓冲区是智能指针管理的,因此子字符串不能挂起。

其核心是别名构造函数。共享指针有两个组成部分:一个引用计数块和一个数据指针。

参考计数块具有强计数、弱计数和销毁功能。

别名构造函数允许您使用不同的共享指针的引用计数块和任意数据指针。这是为了向由共享指针管理的类的成员返回共享指针,这基本上就是您正在做的。

相关内容

  • 没有找到相关文章

最新更新