将 RAII 与字符指针结合使用
我看到很多 RAII 示例类都围绕着文件句柄。
我尝试将这些示例改编为字符指针,但没有成功。
我正在使用的库具有获取字符指针地址的函数(声明如下 get_me_a_string(char **x))。 这些函数为该字符指针分配内存,并将其留给库的最终用户在自己的代码中清理它。
所以,我的代码看起来像这样......
char* a = NULL;
char* b = NULL;
char* c = NULL;
get_me_a_string(&a);
if(a == NULL){
return;
}
get_me_a_beer(&b);
if(b == NULL){
if(a != NULL){
free(a);
}
return;
}
get_me_something(&c);
if(c == NULL){
if(a != NULL){
free(a);
}
if(b != NULL){
free(b);
}
return;
}
if(a != NULL){
free(a);
}
if(b != NULL){
free(b);
}
if(a != NULL){
free(b);
}
听起来 RAII 是我上面这个混乱的答案。 有人可以提供一个简单的 C++ 类来包装 char* 而不是 FILE* 吗?
谢谢
I see a lot of RAII example classes wrapping around file handles.
I have tried to adapt these examples without luck to a character pointer.
A library that I am using has functions that take the address of a character pointer (declared like get_me_a_string(char **x)).
These functions allocate memory for that character pointer and leave it up to the end user of the library to clean it up in their own code.
So, I have code that looks like this...
char* a = NULL;
char* b = NULL;
char* c = NULL;
get_me_a_string(&a);
if(a == NULL){
return;
}
get_me_a_beer(&b);
if(b == NULL){
if(a != NULL){
free(a);
}
return;
}
get_me_something(&c);
if(c == NULL){
if(a != NULL){
free(a);
}
if(b != NULL){
free(b);
}
return;
}
if(a != NULL){
free(a);
}
if(b != NULL){
free(b);
}
if(a != NULL){
free(b);
}
It sounds like RAII is the answer for this mess that I have above.
Could someone provide a simple C++ class that wraps a char* rather than a FILE*?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
标准库中已经有一些可用的东西:它被称为
std::string
。
编辑:根据新信息:
对于实现者来说,这是一个糟糕的设计——分配的模块应该负责释放。
好的,现在我已经将其从系统中删除了:您可以使用
boost::shared_ptr
进行释放。There's something available already in the standard library: it's called
std::string
.Edit: In light of new information:
This is poor design on the implementor's part -- the module that allocates should be responsible for deallocation.
Okay, now that I've got that out of my system: you could use a
boost::shared_ptr
for freeing.一个非常基本的实现(您应该使其不可复制等)。
从技术上讲,这不是 RAII,因为正确的初始化发生在构造函数之后,但它会负责清理工作。
A very basic implementation (that you should make noncopyable etc).
This is technically not RAII, as proper initialization happens later than at the constructor, but it will take care of cleanup.
您可以尝试这样的方法:
这不是最可靠的解决方案,但足以达到目的。
PS:我想知道
std::tr1::shared_ptr
与自定义删除器也可以工作吗?You could try something like this:
It is not the most reliable solution, but could be enough for the purpose.
PS: I'm wondering would
std::tr1::shared_ptr
with custom deleter work as well?我认为 auto_ptr 是您想要的
,或者如果 auto_ptr 语义不适合您,则增强共享指针
i think auto_ptr is what you want
or boost shared_ptr if the auto_ptr semantics dont work for you
使用普通
std::string
或 boost::scoped_array 用于本地数组,或 boost::shared_array 用于共享字符串(后者允许您提供自定义删除器来调用free()
。)Either use plain
std::string
, or boost::scoped_array for local arrays, or boost::shared_array for shared strings (the latter allows you to provide custom deleter to callfree()
.)谢谢大家的回答。
不幸的是,我不能在这个项目中使用 boost 或其他库......所以所有这些建议对我来说都是无用的。
我已经研究过诸如 C 中的异常处理之类的东西,如下所示......
http://www.halfbakery.com/idea/C_20exception_20handling_20macros
然后我研究了为什么 C++没有像Java那样的finally并且遇到了这个RAII的东西。
我仍然不确定我是否会采用析构函数方式并仅使用 C++ 编写代码,还是坚持使用 C 异常宏(使用可怕的 goto:)
Tronic 建议如下所示。
对于 RAII,或者一般的析构函数,它们应该是防段错误的吗?我猜不是。
我唯一不喜欢的是我现在必须在 printf 语句中使用强制转换 (char*)。
Thanks everyone for your answers.
Unfortunately, I cannot use boost, or other libraries on this project... so all of those suggestions are useless to me.
I have looked at things like exception handling in C like here...
http://www.halfbakery.com/idea/C_20exception_20handling_20macros
And then I looked at why C++ doesn't have a finally like Java does and came across this RAII stuff.
I'm still not sure if I will go the destructor way and make the code C++ only, or stick with C exception macro's (which use the dreaded goto:)
Tronic suggested something like the following.
With RAII, or destructors in general, are they supposed to be segfault proof? I'm guessing not.
The only thing that I don't like is the fact that I now have to use a cast (char*) in my printf statements.
另一种解决方案是这样的,这就是我用 C 编写此代码的方式:
An alternative solution would be something like this, which is how I would write this code in C:
既然你说你不能使用 boost,那么编写一个不共享或传输资源的非常简单的智能指针并不难。
这是一些基本的东西。您可以指定删除器函子作为模板参数。我不是特别喜欢转换运算符,因此请使用 get() 方法。
随意添加其他方法,如release()和reset()。
Since you are saying you can't use boost, it isn't very hard to write a very simple smart pointer which doesn't share or transfer resources.
Here's something basic. You can specify a deleter functor as a template parameter. I'm not particularly fond of conversion operators, so use the get() method instead.
Add other methods like release() and reset() at will.