智能指针如何处理数组?例如,
void function(void)
{
std::unique_ptr<int> my_array(new int[5]);
}
Run Code Online (Sandbox Code Playgroud)
当my_array超出范围并被破坏时,整个整数数组是否会被重新声明?只回收了数组中的第一个元素吗?或者还有其他事情发生(例如未定义的行为)?
这个答案引用了N4082,它表明即将进行的更改std::shared_ptr将允许两者T[]和T[N]变体:
不同于
unique_ptr用于阵列部分特,都shared_ptr<T[]>和shared_ptr<T[N]>将是有效的,都将导致delete[]被称为对象的管理的阵列上.Run Code Online (Sandbox Code Playgroud)template<class Y> explicit shared_ptr(Y* p);要求:
Y应为完整类型.表达式delete[] p,当T是数组类型时,或者delete p,当T不是数组类型时,应该是格式良好的,应该具有良好定义的行为,并且不应抛出异常.如果T是U[N],Y(*)[N]应转换为T*; 当T是U[],Y(*)[]应转变成T*; 否则,Y*应可转换为T*.
除非我弄错了,Y(*)[N]否则只能通过获取数组的地址来形成,这显然不能被a拥有或删除shared_ptr.我也没有看到任何N以任何方式强制使用托管对象大小的指示.
允许T[N]语法的动机是什么?它是否产生任何实际效益,如果是,它是如何使用的?
如何动态分配shared_ptr指向的"n个元素"?
我能够创建一个共享指针指向的静态数组,但我希望用户输入一个数字,然后分配n个元素.
shared_ptr<int[10]> p = make_shared<int[10]>();
Run Code Online (Sandbox Code Playgroud) 我想知道这个事实背后的基本原理是什么,std::shared_ptr没有定义[]数组的运算符.特别是为什么std::unique_ptr这个运算符的功能却没有std::shared_ptr?
我想知道为什么动态数组直接支持std::unique_ptr<>但不支持std::shared_ptr<>:
unique_ptr<int[]> ptr1(new int[n]); /// OK!
shared_ptr<int[]> ptr2(new int[n]); /// Incorrect: will not call delete[]
Run Code Online (Sandbox Code Playgroud)
更新:我发现第二行可以改写为:
shared_ptr<int> ptr2(new int[n], default_delete<int[]>());
Run Code Online (Sandbox Code Playgroud)
现在我想知道幕后发生了什么,这使得std::shared_ptr采用第二种方法而不是类似的方式std::unique_ptr?
是否可以对shared_ptr <>指向的数组使用make_shared和自定义删除器(下面是我尝试通过构造函数执行此操作的方式,但我不知道如何通过使用make_shared工作)?
int n = 5;
shared_ptr<int> a(new int[n], default_delete<int[]>());
Run Code Online (Sandbox Code Playgroud)
我想让它看起来像是类似的东西,但是为int数组分配内存并且还有一个自定义删除器.那可能吗?
int n = 5;
shared_ptr<int> a;
a = make_shared<int>();
Run Code Online (Sandbox Code Playgroud) 我想在我的应用程序中使用BOOST Smart指针进行内存管理.但是我不确定我应该将哪个智能指针用于动态分配的数组shared_ptr或shared_array.
根据BOOST文档Starting with Boost release 1.53,shared_ptr可用于保存指向动态分配的数组的指针.
所以我现在想知道用户应该使用shared_array而不是shared_ptr的目的是什么.
我让前两行起作用:
std::shared_ptr<string> sp( new string[3], []( string *p ) { delete[] p; } );
*sp = "john";
auto p = &(* sp);
++p = new string("Paul");
++p = new string("Mary");
for(auto q = &(*sp); q <= p; q++) cout << *q << endl;
Run Code Online (Sandbox Code Playgroud)
(1) 有人可以告诉我如何访问数组的后续元素并使用 for 循环将它们打印出来吗?
我的 for 循环不会使用 MSVC V19 打印任何内容,而 g++ v4.9 打印“john”,但不打印“Paul”和“Mary”,然后给我一个分段错误。
现在,经过更多的 google/bing 搜索,我发现了一些讨论,建议unique_ptr如果我不共享它,我应该使用它。
所以我必须进行更多尝试,这很有效:
const int len=3;
std::unique_ptr<string[]> up( new string[len] ); // this will correctly call delete[] …Run Code Online (Sandbox Code Playgroud) #include <memory>
int main()
{
std::shared_ptr<double> array (new double [256], [](double * d){
delete [] d;
});
}
Run Code Online (Sandbox Code Playgroud)
我shared_ptr指出了一系列具有自己的自定义删除器的双打.
现在我该如何访问阵列?假设我希望在索引处访问数组1.我尝试了通常的"支架方法",但我得到了错误.
array默认情况下,该词指向其第一个元素,但如果我想访问第二个元素该怎么办?使用增量和括号给我"操作员不匹配"错误.
有人可以向我解释一下发生了什么事吗?
我问这个用于研究目的,尽管意识到unique_ptr并且vector会做得更好.
我正在阅读《Effective C++ 第三版》。在第 70 页,作者说道:
与几乎所有智能指针类一样,
tr1::shared_ptr也auto_ptr重载指针解引用运算符(operator->和operator*),这允许隐式转换为底层原始指针(...)
然后,他展示了一个示例(当时shared_ptr是其中的一部分),该示例具有基于名为 的类的隐式转换:tr1Investment
shared_ptr<Investment> pi1();
bool taxable1 = !(pi1->isTaxFree());
^implicit conversion
shared_ptr<Investment> pi2();
bool taxable2 = !((*pi2).isTaxFree());
^implicit conversion
Run Code Online (Sandbox Code Playgroud)
好吧,从那时起我就写了一些测试用例,并且unique_ptr它们是有效的。
我还发现了有关unique_ptr支持数组的信息,并且shared_ptr也将继续(请参阅注释)。但是,在我的测试中,隐式转换似乎不适用于数组周围的智能指针。
示例:我希望这是有效的......
unique_ptr<int[]> test(new int[1]);
(*test)[0] = 5;
Run Code Online (Sandbox Code Playgroud)
但根据我的编译器(Visual C++ 2015 Update 3),事实并非如此。
然后,通过一点研究,我发现一些证据表明根本不支持隐式转换......例如:https: //herbsutter.com/2012/06/21/reader-qa-why-不要隐式转换为现代智能指针。
此时我很怀疑。它是否支持(标准) ?
注意:这本书在这个主题上可能有点过时,因为作者还在第 65 页上说“没有任何类似auto_ptr或tr1::shared_ptr用于动态分配数组的东西,即使在 TR1 中也没有”。