std::auto_ptr 的最佳实践

发布于 2024-10-07 12:50:40 字数 406 浏览 6 评论 0原文

我刚刚习惯使用 std::auto_ptr 的智能指针。

假设我想调用一个同时具有 auto_ptr 和普通指针的函数。

auto_ptr<uint32> data_smart(new uint32[123])]);
uint32 data_fix[123];
uint32* data_dumb = new uint32[123];

processData(data_smart);
processData(data_fix);
processData(data_dumb);

在不超载的情况下,最佳实践是什么?有带有 uint32* 参数的 processData 函数吗?在这种情况下,我可以使用 .get() 将智能指针强制转换为 uint32* 吗?或者说我应该采取什么方法呢? 提前致谢!

I'm just getting used to smart pointers using std::auto_ptr.

Assume that I want to call a function with both auto_ptr and normal Pointers.

auto_ptr<uint32> data_smart(new uint32[123])]);
uint32 data_fix[123];
uint32* data_dumb = new uint32[123];

processData(data_smart);
processData(data_fix);
processData(data_dumb);

What is the best practice for this without overloading? Having the processData function with a uint32* argument? Can I cast the smart pointer to uint32* for this case with .get()? Or what is the way I should do it?
Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

甜心 2024-10-14 12:50:40

1.

auto_ptr<uint32> data_smart(new uint32[123])]);

不要那样做。 auto_ptr 仅适用于标量(它调用 delete 而不是 delete[])。

2.
auto_ptr 拥有它指向的对象,因此除非您想将所有权传递给该函数(在您的代码中不需要),否则该函数应该接受普通指针。因此,您应该将调用更改为:

processData(data_smart.get());

以便明确表示 data_smart 继续拥有该对象。

1.

auto_ptr<uint32> data_smart(new uint32[123])]);

Don't do that. auto_ptr works with scalars only (it calls delete rather than delete[]).

2.
auto_ptr owns the object it points to, so unless you want to pass the ownership to that function (in your code you don't), the function should accept a normal pointer. So you should change the call to:

processData(data_smart.get());

in order to explicitly express that data_smart continues to own the object.

天涯离梦残月幽梦 2024-10-14 12:50:40

编辑:诺亚·罗伯茨对你的问题的评论是这里更大的问题,但这回答了所提出的问题,即使示例代码是错误的......


...没有重载...

如果您想在不重载的情况下执行此操作,则适用于所有这些的唯一选择是使该方法采用哑指针参数。

对于这种情况,我可以将智能指针强制转换为 uint32* 吗?

不可以。使用 std::auto_ptr::get()

EDIT: Noah Roberts' comment on your question is the bigger issue here, but this answers the question asked even if the example code is wrong....


... without overloading ...

If you want to do it without overloading, the only option that's going to work for all of these is to make the method take a dumb pointer parameter.

Can I cast the smart pointer to uint32* for this case?

No. Use std::auto_ptr<t>::get().

不乱于心 2024-10-14 12:50:40

首先,您不使用指向数组的指针来初始化 auto_ptr。它不受支持,最终会导致内存泄漏。 std::auto_ptr 仅处理单个对象。

如果您仍然想使用 std::auto_ptr,但仅适用于单个对象,则需要记住 std::auto_ptr 在复制构造函数中转移所有权。这意味着如果您按值传递 data_smart,则在调用 processData 后,本地 auto_ptr (data_smart) 将不会保留任何内存。

最后,您可能想使用 boost::scoped_array 或 boost::shared_array。

First of all, you don't initialize auto_ptr with a pointer to array. It's not supported, and you'll end up with memory leaks. std::auto_ptr handles only single objects.

If you still want to use std::auto_ptr, but for single objects only, you need to remember that std::auto_ptr transfers ownership in copy constructor. That means that your local auto_ptr (data_smart) won't hold any memory after you call processData if you pass data_smart by value.

In the end, you probably want to use boost::scoped_array or boost::shared_array.

℡寂寞咖啡 2024-10-14 12:50:40

最佳实践是不要使用 auto_ptr。它将在 C++0x 中弃用,并由 std::unique_ptr 取代(参考:C++0x 标准草案,附录 D,第 10 段)。与此同时,替代方案包括 std::tr1::shared_ptr 和 boost::scoped_ptr。

但您的示例是一个数组,而这些指针类型不适用于数组。您可以使用 boost::shared_array 来实现这一点。

然而标准本身没有数组智能指针。这可能是因为他们认为您应该使用 std::vector (或者当您在编译时知道大小时使用 std::array 来表示固定大小的数组)。鉴于此,您可以执行以下操作:

std::vector<uint32> dataVector;
data.reserve(123);

// or, if the size is always 123:
std::tr1::array<uint32, 123> dataArray;

现在,您可以调用接受常规普通 uint32* 的函数,因为 vectorstd:: tr1::arrays 有方法让您以 C 风格数组的指针的形式访问数据:

processData(&dataVector[0]);
processData(dataArray.data());

如果您打算这样做,我会强烈建议添加边界检查。将第二个参数传递给 processData 以及数组的大小:

processData(&dataVector[0], dataVector.size());

如果您可以完全放弃 C 风格的指针/数组,更好的方法可能是通过引用传递:

void processData(std::vector<uint32>& data) {
    // process the data
}

// call it like this:
processData(dataVector);

但这仅适用于 向量,而不是std::tr1::array或任何其他容器。因此,更进一步,您可以使用接受迭代器的模板:

template <class AnIterator>
void processData(AnIterator begin, AnIterator end) {
    for (AnIterator it = begin; it != end; ++it) {
        // process each item
    }
}

// call it like this
processData(dataVector.begin(), dataVector,end());

// or like this
processData(dataArray.begin(), dataArray.end());

// or even like this (assume c_data is a C-style array):
processData(c_data, c_data + number_of_items_in_c_data);

最后一个模板可以工作,因为指向 C 样式数组的指针可以用作迭代器。

Best practice is to not use auto_ptr. It will be deprecated in C++0x and replaced by std::unique_ptr (Reference: C++0x Draft Standard, Appendix D, Paragraph 10). In the meantime, alternatives include std::tr1::shared_ptr and boost::scoped_ptr.

But your example is an array, and those pointer types are not for arrays. You can use boost::shared_array for that.

However the Standard itself does not have array smart pointers. That’s probably because they believe you should be using std::vector instead (or std::array for fixed size arrays when you know the size at compile time). Given that, you could do the following:

std::vector<uint32> dataVector;
data.reserve(123);

// or, if the size is always 123:
std::tr1::array<uint32, 123> dataArray;

Now, you can call your function that accepts a regular plain-old uint32* because both vectors and std::tr1::arrays have methods to give you access to the data as a pointer to a C-style array:

processData(&dataVector[0]);
processData(dataArray.data());

I would strongly recommend adding bounds-checking if you are going to do this. Pass a second argument to processData with the size of the array:

processData(&dataVector[0], dataVector.size());

And if you can abandon C-style pointer/arrays entirely, a better way might be to pass by reference:

void processData(std::vector<uint32>& data) {
    // process the data
}

// call it like this:
processData(dataVector);

But this only works for vectors, not std::tr1::arrays or any other container. So, taking it one step further, you could use a template that accepts iterators:

template <class AnIterator>
void processData(AnIterator begin, AnIterator end) {
    for (AnIterator it = begin; it != end; ++it) {
        // process each item
    }
}

// call it like this
processData(dataVector.begin(), dataVector,end());

// or like this
processData(dataArray.begin(), dataArray.end());

// or even like this (assume c_data is a C-style array):
processData(c_data, c_data + number_of_items_in_c_data);

The last one works because pointers to C-style arrays can be used as iterators.

神经大条 2024-10-14 12:50:40

在您的情况下,使用向量是最安全的选择:

std::vector<uint32> data(123);

processData 的签名理想情况下应该是:

void processData(const std::vector<uint32> & data);

但是,这个签名更常用:

void processData(uint32 * bytes, int length);

在这两种情况下,您都可以使用向量:

// 1
processData(data);

// 2
processData(data.data(), data.size());

In your situation using a vector is the safest choice:

std::vector<uint32> data(123);

The signature of processData should ideally be:

void processData(const std::vector<uint32> & data);

However, this one is more frequently used:

void processData(uint32 * bytes, int length);

In both cases you can use the vector:

// 1
processData(data);

// 2
processData(data.data(), data.size());
永不分离 2024-10-14 12:50:40

尽管为什么您应该使用 auto 和哑(正如您所说的)指针将相同的数据指向相同的名称函数而不重载,但 auto_ptr 不能在数组上使用,因为它调用了错误类型的删除。

看看这个:http://learningcppisfun。 blogspot.com/2007/05/custom-deleters-with-smart-pointers.html

另外看看这个关于数组智能指针的问题:数组的 auto_ptr

Not withstanding why you should want to use auto and dumb (as you put it) pointers for the same data to the same name function without overloading, auto_ptr cannot be used on arrays because it calls the wrong sort of delete.

Have a look at this: http://learningcppisfun.blogspot.com/2007/05/custom-deleters-with-smart-pointers.html

Also have a look at this SO question regarding smart pointers to arrays: auto_ptr for arrays

苍风燃霜 2024-10-14 12:50:40

让我觉得有趣的是,data_smart 变量是这三个变量中最愚蠢的一个。也就是说,当该作用域结束时,auto_ptr 析构函数将对其指针调用 delete 而不是 delete[] ,这会导致 UB (这比可能的内存更糟糕)从 data_dumb 泄漏)。

所以,重点是不要对数组使用 auto_ptr,而使用向量。

进入真正的问题。首先,如果可能的话,使用引用参数而不是指针参数。如果这不可能,请使用裸指针,并且 auto_ptr::get() 可以访问底层指针。

It amuses me that the data_smart variable is the dumbest of the three. That is, when that scope ends, the auto_ptr destructor is going to call delete on its pointer and not delete[] which leads to UB (which is worse than the possible memory leak from data_dumb).

So, the point is don't use auto_ptr for arrays, use vector.

Onto the real question. First, if possible use reference arguments instead of pointer arguments. If this isn't possible use bare pointers and auto_ptr::get() gives access to the underlying pointer.

怪我闹别瞎闹 2024-10-14 12:50:40

忽略已经被锤击的不要在数组上使用 auto_ptr 。

在不超载的情况下,最佳实践是什么?

看来你的方法不会取得所有权,所以剩下的问题是它会改变吗?

processData 函数带有 uint32* 参数吗?

processData( uint32* ) 这是一种选择,但可能不是最好的。
processData( uint32[123] ) 如果您不进行编辑(123 开始推送一些复制)。
processData( uint32 &[123] ) by ref 并根据需要应用 const。

在这种情况下,我可以使用 .get() 将智能指针强制转换为 uint32* 吗?

您可以使用 get() 获取智能指针的指针内容,它已经“类型化”了,因此无需对其进行强制转换。

旁白:
如此原始级别的数据和操作应该在一个类中,您甚至可能不需要将成员变量传递到成员函数中。

Ignoring the already HAMMERED don't use auto_ptr on array.

What is the best practice for this without overloading?

It appears your method will not take ownership, so the remaining question is will it be changed?

Having the processData function with a uint32* argument?

processData( uint32* ) Thats one option, but maybe not the best.
processData( uint32[123] ) if your not editing (123 is starting to push some copying).
processData( uint32 &[123] ) by ref and apply const as necessary.

Can I cast the smart pointer to uint32* for this case with .get()?

You can get the pointer content of the smart pointer using get(), it's already 'typed' so no need to cast it.

Aside:
Data and manipulation of at such a raw level should be in the one class, you probably don't even need to pass what should be a member variable into a member function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文