2

到目前为止,我已经为一些数据处理分配了一个缓冲区,然后将其删除。由于代码变得更大并且可能会在某些时候捕获异常,因此我考虑使用 a 使其更安全std::unique_ptr并提出了这些解决方案:

unique_ptr<char, void (*)(void *)> p1( (char*)operator new(bufSize), operator delete);
unique_ptr<char[], void (*)(void *) > p2( (char*)operator new(bufSize), operator delete);

memcpy(&((p1.get())[0]), "xyz", 3);
memcpy(&(p2[0]), "xyz", 3);

char x1 = p1.get()[0];
char x2 = p2[0];

对我来说,第一个解决方案 (p1) 似乎是正确的,但是编写 (p1.get())[...] 很乏味

第二种解决方案是方便的,但这是我的问题:

std::unique_ptr<T[]>似乎以一种特殊的方式支持模板化operator[],这让我想知道,如果我使用std::unique_ptr<T[]>自定义的 new 和 delete 操作,``operator[] 或任何其他功能是否有任何问题,或者是第二种解决方案( p2) 好吗?

4

3 回答 3

10

std::unique_ptr专门用于数组。你可以只写以下内容:

std::unique_ptr<char[]> str(new char[4]);
char foo[] = "str";
std::copy(foo, foo + sizeof(foo), &str[0]);

如果不存在,您可以自己做类似的事情,或者您可以编写一个using别名和一个make_array为您进行设置并返回正确类型的函数,那么使用它就像

auto str = make_array<char>(4);

… 或类似的东西。

于 2012-12-22T16:41:19.270 回答
2

除非绝对需要,否则不要使用原始缓冲区(并且很少需要使用原始缓冲区)。您可能最好将 normalnew char[n]与 一起使用std::unique_ptr<char[]>

std::unique_ptr<char[]> array(new char[n]);

如果您绝对需要分配原始内存,则可以使用std::unique_ptr<char[], void (*)(void*)>,但删除函数需要与分配函数匹配,即,operator delete[]如果您使用operator new[].

于 2012-12-22T16:51:56.260 回答
0

std::unique_ptr支持动态数组的管理。您不需要编写自己的删除器:

例子:

int main()
{
    int letter{97};
    int size{26};

    unique_ptr<char[]> arr(new char[size]());

    for (int i{}; i != size; ++i)
        arr[i] = static_cast<char>(letter++); // supports subscript

    for (int i{}; i != size; ++i)
        cout << arr[i];
}

Whilestd::shared_ptr不直接支持动态数组的管理,需要自己编写删除器:

例子:

int main()
{
    int letter{97};
    int size{26};

    shared_ptr<char> arr(new char[size](), [](char *p) { delete [] p; }); // own deleter

    for (int i{}; i != size; ++i)
        *(arr.get() + i) = static_cast<char>(letter++);

    for (int i{}; i != size; ++i)
        cout << *(arr.get() + i);
}

由于std::shared_ptr没有下标运算符并且不支持指针运算,我们可以使用get()来获取内置指针。

于 2015-09-20T04:24:49.937 回答