据我所知,智能指针与“原始”指针应该是等价的,区别在于它是安全的。好的,但如果我有常规指针:
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)?
答案 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
}