如何索引到c++ shared_ptr/unique_ptr数组
How to index into C++ shared_ptr/unique_ptr array?
灵感来自共享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;
(1)有人能告诉我如何访问我的数组的后续元素,并打印出他们与for循环?
我的for循环在MSVC V19和g++ v4.9中不打印任何东西,打印"john"但不打印"Paul"answers"Mary",然后给我一个分段错误。
现在经过更多的谷歌/bing搜索,我发现一些讨论建议我应该使用unique_ptr
,如果我不分享它。
所以我做了更多的实验,这是可行的:
const int len=3;
std::unique_ptr<string[]> up( new string[len] ); // this will correctly call delete[]
up[0] = "john";
up[1] = "paul";
up[2] = "mary";
for(int ii = 0; ii < len; ++ii) cout << up[ii] << endl;
(2)有没有一种方法来打印数组没有硬编码的长度常数?我希望有一种方法可以使新的c++ for循环语法工作,但它似乎只适用于std::array
和std::vector
。
(3)是否有更简单的方法来初始化这个数组?也许有一个初始化列表?
使用shared_ptr::get
成员函数访问后续元素
std::shared_ptr<string> sp( new string[3], std::default_delete<string[]>() );
sp.get()[0] = "John";
sp.get()[1] = "Paul";
sp.get()[2] = "Mary";
for(auto q = sp.get(); q < sp.get() + 3; q++) cout << *q << endl;
解引用shared_ptr
的问题是它会返回一个string&
,但是你想要访问底层指针,以便能够索引到下一个元素。
你也可以在构造shared_ptr
数组时使用列表初始化
std::shared_ptr<string> sp( new string[3]{"John", "Paul", "Mary"},
std::default_delete<string[]>() );
对于unique_ptr
,正如您所注意到的,存在部分专门化,可以正确地删除数组类型。但是,它不存储数组的长度,您需要单独存储它,并将其与unique_ptr
一起传递。对于单行初始化,您可以使用与上述相同的语法。
std::unique_ptr<string[]> up( new string[len]{"John", "Paul", "Mary"} );
然而,shared_ptr
和unique_ptr
都不能用于基于范围的for循环。for范围的指定要求操作数要么是数组,要么必须具有begin()
和end()
成员函数,或者该范围的开始迭代器和结束迭代器必须由ADL分别使用表达式begin(__range)
和end(__range)
获得。包含数组的shared_ptr
或unique_ptr
都不满足这些条件。
除非你有很好的理由不这样做,否则你应该只使用std::vector<std::string>
,这将节省你单独跟踪数组长度的麻烦。如果您在编译时知道数组的长度,那么std::array<std::string, N>>
也是另一种选择。
在c++ 17中,operator[]
是为shared_ptr<T[]>
(link)定义的。在此之前,unique_ptr
有,但shared_ptr
没有。
所以,下面的代码可以工作:
std::shared_ptr<string[]> sp(new string[3]);
sp[0] = "John";
sp[1] = "Paul";
sp[2] = "Mary";
for(int i =0; i< 3; i++)
{
cout<<sp[i]<<"n";
}
注意,它是为shared_ptr<T[]>
定义的,而不是为shared_ptr<T>
定义的,即当你有一个动态分配的数组时。此外,我已经删除了您的自定义删除器,因为您的删除器类似于编译器将使用的默认删除器,但是您可以自由添加它。
对于你的第二个查询-能够使用新的c++ For循环(基于范围的For循环),你不能直接使用这个智能指针,因为基于范围的For循环只适用于具有begin()
, end()
, operator++
, operator*()
和operator!=
定义的容器(链接)。最简单的方法是使用预先分配大小的std::vector。如。vector<T> sp(3)
或vector<T> sp; sp.reserve(3)
。这和你的智能指针方法一样有效。要获得底层内存,您可以使用vector<T>::data()
eg。sp.data()
。这将给你一个包含3个元素的动态C数组(一般为n个元素)。
如何索引到c++
shared_ptr
/unique_ptr
数组?
您已经显示了unique_ptr
的代码。
这适用于shared_ptr
.
std::shared_ptr<string> sp( new string[3], []( string *p ) { delete[] p; } );
sp.get()[0] = "string 1";
sp.get()[1] = "string 2";
sp.get()[2] = "string 3";
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- C++中的指针否定 (!ptr == NULL)
- 从const ptr*转换为ptr*时出现问题
- 无法使用 libtool 将 -shared 参数传递给 g++
- boost::shared_ptr和std::shared-ptr的同居
- 我可以用std::shared_ptr而不是boost::shared-ptr构建boost库吗
- shared-ptr-C++shared_ptr与unique_ptr用于资源管理