C++ 在这种情况下如何使用智能指针

C++ 在这种情况下如何使用智能指针,c++,smart-pointers,C++,Smart Pointers,我想在以下情况下使用智能指针: SOME_STRUCT* ptr = new SOME_STRUCT; ptr->SOME_MEMBER = new BYTE[100]; CallSomeAPI(ptr); 现在API可以返回错误或成功通过,但在这两种情况下,我都想删除对象,一种方法是在错误退出和正常退出期间编写delete语句 但是我如何使用智能指针来处理这些指针呢? 所谓智能指针,我指的是唯一的、共享的等等,无论哪种都可以 谢谢 您可以为unique\u ptr编写

我想在以下情况下使用智能指针:

   SOME_STRUCT* ptr = new SOME_STRUCT;
   ptr->SOME_MEMBER = new BYTE[100];
   CallSomeAPI(ptr);
现在API可以返回错误或成功通过,但在这两种情况下,我都想删除对象,一种方法是在错误退出和正常退出期间编写delete语句

但是我如何使用智能指针来处理这些指针呢? 所谓智能指针,我指的是唯一的、共享的等等,无论哪种都可以


谢谢

您可以为
unique\u ptr
编写自定义删除程序

struct my_deleter {
    void operator()(SOME_STURCT* ptr) const {
        delete[] ptr->SOME_MEMBER;
        delete ptr;
    }
};

using my_ptr = std::unique_ptr<SOME_STRUCT, my_deleter>;
struct my\u deleter{
void运算符(){
删除[]ptr->某些成员;
删除ptr;
}
};
使用my_ptr=std::unique_ptr;
我建议改变
新的结构
新的一些结构{}
默认初始化
某些\u成员
nullptr

struct my_deleter {
    void operator()(SOME_STURCT* ptr) const {
        delete[] ptr->SOME_MEMBER;
        delete ptr;
    }
};

using my_ptr = std::unique_ptr<SOME_STRUCT, my_deleter>;

我对这个解决方案不是100%满意,所以也许可以研究一下
scope\u-guard
或者为您的结构编写一个包装类。

我假设您不能修改
SMOE\u-struct
来添加析构函数。这给您留下了两个选项:自定义删除器和封装

首先,您可以创建一个用于
std::unique\u ptr

struct SOME_STRUCT_Deleter
{
  void operator() (SOME_STRUCT *p) const
  {
    delete[] p->SOME_MEMBER;
    delete p;
  }
};

std::unique_ptr<SOME_STRUCT, SOME_STRUCT_Deleter> ptr{new SOME_STRUCT};
ptr->SOME_MEMBER = new BYTE[100];
CallSomeAPI(ptr.get());
我认为最好的第二个选项是包装
SOME结构

struct SOME_STRUCT_plus_plus
{
  SOME_STRUCT s;
  ~SOME_STRUCT_plus_plus()
  {
    delete[] s.SOME_MEMBER;
  }

  SOME_STRUCT_plus_plus()
  {
    s.SOME_MEMBER = new BYTE[100];
  }
};

std::unique_ptr<SOME_STRUCT_plus_plus> ptr{new SOME_STRUCT_plus_plus};
CallSomeAPI(&ptr->s);
struct SOME\u struct\u plus\u plus
{
一些结构;
~SOME_STRUCT_plus_plus()
{
删除[]s.SOME_成员;
}
一些_STRUCT_plus_plus()
{
s、 SOME_成员=新字节[100];
}
};
std::unique_ptr ptr{newsome_STRUCT_plus_plus};
CallSomeAPI(&ptr->s);

您甚至可以通过使
SOME\u STRUCT\u plus\u plus
SOME\u STRUCT
派生来“包装”它,而不是聚合它,这样您就可以直接访问成员,而无需通过
s
。同时,如果有人将
SOME\u STRUCT\u plus\u plus*
强制转换为
SOME\u STRUCT*
,然后在其上调用
delete
,则可能导致内存泄漏。

这里,似乎所有内容都可以放在堆栈上:

SOME_STRUCT ptr;         // or auto ptr = std::make_unique<SOME_STRUCT>();
BYTE bytes[100];         // or std::vector<BYTE> bytes(100);
ptr.SOME_MEMBER = bytes; // or ptr->SOME_MEMBER = bytes.data();
CallSomeAPI(&ptr);       // or CallSomeAPI(ptr.get());
SOME_STRUCT ptr;//或自动ptr=std::make_unique();
字节[100];//或std::向量字节(100);
ptr.SOME_成员=字节;//或ptr->SOME_MEMBER=bytes.data();
CallSomeAPI(&ptr);//或CallSomeAPI(ptr.get());

为什么要使用
std::unique\u ptr
?新的智能指针实际上不应该被看作是普通指针的替代品,而是更像是处理所有权:一个资源(内存、文件、设备等)可以由多个所有者(
std::shared_ptr
)拥有,还是只由一个所有者(
std::unique_ptr
)拥有一次?实际上我想用一个智能指针来自动解除分配,不一定是唯一的\u ptr,我的主要目标是自动清理,而不是所有权。我现在对这个问题进行了编辑,以使问题更加清楚。函数接受指针的事实并不意味着它必须动态分配。因为您还说对象没有将函数与代码一起保留,所以在堆栈上创建两个对象以获得自动清理;std::向量缓冲器(100);s、 SOME_成员=&缓冲区[0];CallSomeAPI&s--是的,这很有效。@Ulrich别害羞!发布一个答案!我本来可以编写包装器类,但我不喜欢它,但我更喜欢自定义的deleter方法;-)但是,同样的东西也可以用于共享ptr吗?@shaarang是的,它也可以用于
共享ptr
。创建共享指针时,必须显式提供deleter对象,但不必在
shared\u ptr
类型中反映其类型。添加到答案中。但我更喜欢deleter方法,因为它回答了我的问题,并且我将根据代码的总体结构使用此方法。!:-)这只是我向你们提出的问题的缩小版本,值100不是固定的,实际上是[nCount],所以它不是一个答案。是的,刚刚意识到向量也可以帮助把所有的东西放在堆栈上,即使是这样!谢谢