Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 创建资源并将其返回给调用者释放的最佳接口_C++_Raii - Fatal编程技术网

C++ 创建资源并将其返回给调用者释放的最佳接口

C++ 创建资源并将其返回给调用者释放的最佳接口,c++,raii,C++,Raii,我有一个char*数组,它是new'd,并在函数中初始化。通常我会使用std::string,但数组以null结尾,可能有多个'\0',我希望捕获完整大小 实际上,调用方在使用此函数时必须记住delete[]字符*。我想清理接口,以便在析构函数超出范围时调用delete[],但我不确定该使用什么。是否有一个智能指针可以接受char* 编辑: 我不想使用std::string,因为不清楚这不是一个C风格的空终止字符串。我可以为此使用boost::scoped_数组吗?既然作用域数组是不可复制的,我

我有一个
char*
数组,它是
new
'd,并在函数中初始化。通常我会使用
std::string
,但数组以null结尾,可能有多个
'\0'
,我希望捕获完整大小

实际上,调用方在使用此函数时必须记住
delete[]
字符*。我想清理接口,以便在析构函数超出范围时调用
delete[]
,但我不确定该使用什么。是否有一个智能指针可以接受
char*

编辑:


我不想使用
std::string
,因为不清楚这不是一个C风格的空终止字符串。我可以为此使用
boost::scoped_数组吗?既然
作用域数组
是不可复制的,我如何从创建它的函数返回它?

这就是OO编程的全部内容。像上面的注释一样使用
std::string
,或者为您创建一个处理数据的类:

class MyObj {
private:
   char *data;
   int len;

public:
   MyObj( const char *data, int len ) {
      this->data = new char[...
      // do what you need here
   }

   const char* getStr() const {
      return data;
   }

   int getLen() const {
      return len;
   }

   ~MyObj() {
      delete [] data;
   }
};
您可能还希望实现复制构造函数和赋值运算符(或将其使用私有化)

或者,使用std::string作为基本实现,但仅公开所需内容和方式:

class MyObj : private std::string {
public:
   // whatever you want here
   const char* data() {
      return c_str();
   }

   int length() const {
      return std::string::length();
   }
};

这就是OO编程的全部内容。像上面的注释一样使用
std::string
,或者为您创建一个处理数据的类:

class MyObj {
private:
   char *data;
   int len;

public:
   MyObj( const char *data, int len ) {
      this->data = new char[...
      // do what you need here
   }

   const char* getStr() const {
      return data;
   }

   int getLen() const {
      return len;
   }

   ~MyObj() {
      delete [] data;
   }
};
您可能还希望实现复制构造函数和赋值运算符(或将其使用私有化)

或者,使用std::string作为基本实现,但仅公开所需内容和方式:

class MyObj : private std::string {
public:
   // whatever you want here
   const char* data() {
      return c_str();
   }

   int length() const {
      return std::string::length();
   }
};

2011年之前,从函数返回动态数组的选项有
std::string
std::vector
boost::shared_数组
。有了现代化的实现,您还可以使用
std::unique\u ptr


我建议使用
std::string
表示字符串。

在2011年之前,从函数返回动态数组的选项有
std::string
std::vector
boost::shared_array
。有了现代化的实现,您还可以使用
std::unique\u ptr


我建议使用
std::string
来表示字符串。

std::string
可以包含空字符。如果你真的那么害怕,你总是可以使用
std::vector
@KerrekSB,
std::string
意味着它可以被
c\u str
方法用作常规的空终止字符串。我认为在这种情况下,你推荐的
std::vector
更好,除非你需要一些字符串函数。@MarkRansom:string::c_str()
string::data()
vector::data()
的实用程序几乎相同。你只需要训练你的消费者不要特别对待空值…@KerrekSB,我真的只是在谈论如何使用它的期望,而不是技术限制。最小惊讶原则和所有这些-您不会期望
std::string
包含空值,因此为了避免混淆,即使它完全可以使用,也不要让它使用。@MarkRansom:我支持Kerrek,如果接口的语义是字符串可以包含NUL字符,然后期望用户使用
std::string::length()
std::string::data()
。同样,如果您对类型
T
有一个
std::map
,而该类型不是默认的可构造类型,则用户必须意识到不要使用
运算符[]
,这只是对组件特定用途的限制。
std::string
可以包含空字符。如果你真的那么害怕,你总是可以使用
std::vector
@KerrekSB,
std::string
意味着它可以被
c\u str
方法用作常规的空终止字符串。我认为在这种情况下,你推荐的
std::vector
更好,除非你需要一些字符串函数。@MarkRansom:string::c_str(),
string::data()
vector::data()
的实用程序几乎相同。你只需要训练你的消费者不要特别对待空值…@KerrekSB,我真的只是在谈论如何使用它的期望,而不是技术限制。最小惊讶原则和所有这些-您不会期望
std::string
包含空值,因此为了避免混淆,即使它完全可以使用,也不要让它使用。@MarkRansom:我支持Kerrek,如果接口的语义是字符串可以包含NUL字符,然后期望用户使用
std::string::length()
std::string::data()
。同样地,如果您对类型
T
有一个
std::map
,而该类型不是默认可构造的,那么用户必须意识到不要使用
操作符[]
,这只是对组件特定用途的限制。不要忘记三个规则(如果使用C++11,移动构造函数和移动赋值也是一个好主意)。谢谢你的帖子,但是一个自定义类似乎太过分了。它只是一个char[]我的问题主要是我如何正确地使用RAII,这里有一个智能指针,它是有意义的。我不使用C++。11@Chris,理解,我不知道您的代码的其余部分,但您也可以从不同的角度来看待您的问题。可能是“函数”创建这些数据的方法应该是
MyObj
对象本身的成员方法?或者它可能是对象的构造函数?我发现自己在像您这样的情况下会重新思考代码/数据布局…特别是,如果没有正确的复制或移动语义,这不能用作函数的返回值;在这种情况下,您将重新定义g或者
std::vector