Lok*_*ked 2 c++ design-patterns raii
我希望通过一个例子更好地理解如何使用我的类实现RAII习语:推荐的方法是什么,以确保指针在我的课程中正确免费()?
我有一个课程,应该在课程期间存在.本着RAII的精神,因为我需要将对这个类的引用传递给其他类,我将它保存在shared_ptr中(不确定它实际上需要保存在shared_ptr中,但为了好玩,它是).
在类ctor中,我使用2个缓冲区(指针),然后使用缓冲区然后free()'循环多次malloc().如果发生事故,dtor应包含故障安全代码以释放缓冲区.
dtor可以看到缓冲区的唯一方法是将它们声明为类变量,但它们仅用于类ctor.
例:
class Input
{
private:
PSOMETYPE buffer1;
public:
Input();
~Input();
}
Input::Input() : buffer1(NULL)
{
for(blahblah)
{
buffer1 = (PSOMETYPE)malloc(sizeof(SOMETYPE));
// Do work w/buffer1
if(buffer1 != NULL) { free(buffer1); buffer1 = NULL }
}
}
Input::~Input()
{
if(buffer1 != NULL) { free(buffer1); buffer1 = NULL }
}
Run Code Online (Sandbox Code Playgroud)
考虑到我只在ctor中使用缓冲区,将它声明为私有类变量是否有意义?如果我在ctor的范围内声明它,那么dtor将不知道它是什么来释放.
我知道这是一个简单的例子,老实说,我可以实现这个,因为很容易忘记使用智能指针来引用我的类并且有一个空白的dtor,就像我在循环中做的那样free()'.我没有导师或上学,而且我不确定何时应该遵循RAII成语.
RAII的精神是使用本地对象来管理本地分配的对象,而不是人为地将其生命周期与正在构造的对象联系起来:
class Input
{
// no pointer at all, if it's only needed in the constructor
public:
Input();
// no explicit destructor, since there's nothing to explicitly destroy
};
Input::Input()
{
for(blahblah)
{
std::unique_ptr<SOMETYPE> buffer1(new SOMETYPE);
// or, unless SOMETYPE is huge, create a local object instead:
SOMETYPE buffer1;
// Do work w/buffer1
} // memory released automatically here
}
Run Code Online (Sandbox Code Playgroud)
如果您正在编写一个用于管理该资源的类,那么您应该只需要自己使用delete(或者free或其他) - 并且通常已经有一个标准类(例如智能指针或容器)来执行您的操作想.
当您确实需要编写自己的管理类时,请始终记住规则三:如果析构函数删除了某些内容,则该类的默认复制行为几乎肯定会导致双重删除,因此您需要声明一个复制构造函数并复制-assignment运算符来防止这种情况.例如,在您的课程中,我可以编写以下错误代码:
{
Input i1; // allocates a buffer, holds a pointer to it
Input i2(i1); // copies the pointer to the same buffer
} // BOOM! destroys both objects, freeing the buffer twice
Run Code Online (Sandbox Code Playgroud)
防止这种情况的最简单方法是删除复制操作,因此这样的代码将无法编译:
class Input {
Input(Input const&) = delete; // no copy constructor
void operator=(Input) = delete; // no copy assignment
};
Run Code Online (Sandbox Code Playgroud)
较旧的编译器可能不支持= delete; 在这种情况下,您可以通过私有声明它们来获得几乎相同的效果= delete,而不是实现它们.
| 归档时间: |
|
| 查看次数: |
590 次 |
| 最近记录: |