C++ 正确声明智能指针

C++ 正确声明智能指针,c++,C++,我对此有点困惑: int *pointer = new int[100]; // Yes int array [] = new int[100]; // No 但是: unique_ptr指针{new int[100]};//不 唯一的_ptr数组{new int[100]};//对 有人能解释一下这里涉及的一般原则吗。我不完全理解为什么智能指针语义似乎与常规原始指针相反。智能指针是库代码,所以它们的工作方式是这样的,因为有人以这种方式设计它们 在第一个裸数组新代码中,第二行在语

我对此有点困惑:

int *pointer = new int[100];    // Yes
int array [] = new int[100];    // No
但是:

unique_ptr指针{new int[100]};//不
唯一的_ptr数组{new int[100]};//对

有人能解释一下这里涉及的一般原则吗。我不完全理解为什么智能指针语义似乎与常规原始指针相反。

智能指针是库代码,所以它们的工作方式是这样的,因为有人以这种方式设计它们

在第一个裸数组新代码中,第二行在语法上没有意义,因为不能用指针初始化数组,并且
new
返回指针

unique_ptr
示例也是错误的;更正后的版本更有意义:

//               +--------------+------------ pointer to int
//               V              V
std::unique_ptr<int>   p { new int; }
std::unique_ptr<int[]> p { new int[10]; }
//               ^                ^
//               +----------------+---------- pointer to first element
//                                            of an array of int
//+--------------+-----------指向int的指针
//V V
std::unique_ptr p{new int;}
std::unique_ptr p{new int[10];}
//               ^                ^
//+-------------+--------------指向第一个元素的指针
//整数数组的
找出模式

您需要不同模板专门化的原因是,您需要根据指针的分配方式对其调用
delete
delete[]
,但您无法仅从原始指针看出这一点。(此外,阵列版本还提供了一个方便的
[]
-运算符。)


没有什么能阻止你混合使用
unique\u ptr
new int[10]
,但这或多或少是一个微妙的错误,它会导致沉默的未定义行为(还有一个原因,就是永远不要使用
new
你自己,而是依赖
make\u unique
!)。相比之下,您的第一个示例是一个简单的语法错误。

我100%同意Kerrek SB的答案。在这里,我只想补充另一个强大的可能性。还可以定义自定义删除器类

 auto deleter= [](int* ptr){delete[] ptr;};
 std::unique_ptr<int, decltype(deleter)> ptr4(new int[100], deleter);
autodeleter=[](int*ptr){delete[]ptr;};
std::unique_ptr ptr4(new int[100],deleter);
这看起来很复杂,但是如果您需要调用一些需要C结构的堆分配的C库,那么它可能非常有用

具体例子:GSL GNU科学图书馆。集成例程需要分配一个名为“gsl_集成_工作区”的结构。在这种情况下,您可以使用以下代码来确保您的代码是异常安全的

 auto deleter= [](gsl_integration_workspace* ptr) {
   gsl_integration_workspace_free(ptr);
 };
 std::unique_ptr<gsl_integration_workspace, decltype(deleter)> ptr4 (
 gsl_integration_workspace_alloc (2000), deleter);
auto deleter=[](gsl\u集成\u工作区*ptr){
gsl_集成_工作空间_自由(ptr);
};
标准::唯一的ptr ptr4(
gsl_集成_工作空间_alloc(2000),删除);

正如Kerrek SB所说,因为智能指针是库代码,所以它们提供了比原始指针更强大的内存管理方法。

哦,实际上我是这样做的。有趣!所以
unique\u ptr
甚至没有意义,因为我不应该在智能指针中创建原始指针。这很有帮助。
unique\u ptr
是否能够确定它是否应该调用
delete
delete[]
?@sircodesalot:
unique\u ptr
是一个模板
unique\u ptr
使用
delete
,而
unique\u ptr
使用
delete[]
(其中
T
是非数组类型)——由您决定。啊,好的。知道了。我学到了两个新东西。非常感谢。
 auto deleter= [](gsl_integration_workspace* ptr) {
   gsl_integration_workspace_free(ptr);
 };
 std::unique_ptr<gsl_integration_workspace, decltype(deleter)> ptr4 (
 gsl_integration_workspace_alloc (2000), deleter);