将 RAII 引入 C 的一种解决方案(当您没有 cleanup() 时)是使用将执行清理的代码包装您的函数调用。这也可以打包成一个整洁的宏(在最后展示)。
/* Publicly known method */
void SomeFunction() {
/* Create raii object, which holds records of object pointers and a
destruction method for that object (or null if not needed). */
Raii raii;
RaiiCreate(&raii);
/* Call function implementation */
SomeFunctionImpl(&raii);
/* This method calls the destruction code for each object. */
RaiiDestroyAll(&raii);
}
/* Hidden method that carries out implementation. */
void SomeFunctionImpl(Raii *raii) {
MyStruct *object;
MyStruct *eventually_destroyed_object;
int *pretend_value;
/* Create a MyStruct object, passing the destruction method for
MyStruct objects. */
object = RaiiAdd(raii, MyStructCreate(), MyStructDestroy);
/* Create a MyStruct object (adding it to raii), which will later
be removed before returning. */
eventually_destroyed_object = RaiiAdd(raii,
MyStructCreate(), MyStructDestroy);
/* Create an int, passing a null destruction method. */
pretend_value = RaiiAdd(raii, malloc(sizeof(int)), 0);
/* ... implementation ... */
/* Destroy object (calling destruction method). */
RaiiDestroy(raii, eventually_destroyed_object);
/* or ... */
RaiiForgetAbout(raii, eventually_destroyed_object);
}
您可以使用宏来表达SomeFunction 中的所有样板代码,因为每次调用都相同。
例如:
/* Declares Matrix * MatrixMultiply(Matrix * first, Matrix * second, Network * network) */
RTN_RAII(Matrix *, MatrixMultiply, Matrix *, first, Matrix *, second, Network *, network, {
Processor *processor = RaiiAdd(raii, ProcessorCreate(), ProcessorDestroy);
Matrix *result = MatrixCreate();
processor->multiply(result, first, second);
return processor;
});
void SomeOtherCode(...) {
/* ... */
Matrix * result = MatrixMultiply(first, second, network);
/* ... */
}
注意:您可能希望使用 P99 等高级宏框架来实现上述目标。