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