有没有办法遍历数组上的shared_或任何“智能”ptr?

时间:2012-01-26 08:35:10

标签: c++ smart-pointers

据我所知,智能指针与“原始”指针应该是等价的,区别在于它是安全的。好的,但如果我有常规指针:

int* p = new int[10];
fill(p, p + 10, 0);//this will work for regular pointer but not for smart one.  

与手写循环相同:

for(int i = 0; i < 10; ++i)
{
*p[i] = 0;
}

对于聪明的poiner来说,这是不可能的(我认为)。所以问题是,我如何初始化数组到哪个指针我已经存储在一个智能指针中(让我们假设是shared_ptr)?

2 个答案:

答案 0 :(得分:3)

首先,使用std::vector<int>可能更容易。但是,如果你的数组的大小不变,那么std::vector<int>可能会更好地替换为智能指针。

有了这个,你的首选应该是std::unique_ptr,特别是数组专精:std::unique_ptr<int[]>。 (如果不这样做,智能指针将在指针上使用delete而不是delete[],从而导致未定义的行为。)您的代码将变为:

std::unique_ptr<int[]> p(new int[10]);
std::fill(p.get(), p.get() + 10, 0);

如您所见,智能指针有一个get()方法返回基础指针。

从这里开始,如果你需要使用std::shared_ptr,那么事情就变得非常危险(据我所知,不幸的是疏忽了)。这种疏忽是std::shared_ptr没有数组专门化:

{
    std::shared_ptr<int> x(new int[10]);
} // oops! calls delete x.get(); instead of delete [] x.get(); ... UB!

但是,std::shared_ptr可以很容易地纠正这个:

{
    std::shared_ptr<int> x(new int[10], std::default_delete<int[]>());
} // correctly uses delete [] x.get()

从这一点来看,代码是相同的:

std::shared_ptr<int> p(new int[10], std::default_delete<int[]>());
std::fill(p.get(), p.get() + 10, 0);

请注意,std::shared_ptr提供了一个构造函数,可以从std::unique_ptr构造,它正确地使用了删除器。所以这是安全的:

std::unique_ptr<int[]> p(new int[10]);
std::shared_ptr<int> p2(std::move(p)); // okay, uses std::default_delete<int[]>()

答案 1 :(得分:0)

假设您使用类似这样的智能指针声明您的数组:

boost::shared_array<int> p = new int[10];

fill - 函数的调用如下所示:

fill(p.get(), p.get() + 10, 0);

p.get()返回由智能指针管理的原始指针。你的循环不需要调整,但首先是错误的:

for(int i = 0; i < 10; ++i) {
    p[i] = 0; // no dereferencing required here
}