最近,我遇到了一个例子,我的析构函数需要接受一个参数。
我正在开发一个 C 包,它在内部管理内存并使用它自己的参数跟踪分配和释放。我不想打破它。
我写了一个 C 代码,初始化我自己的数据结构并在最后释放它们。当我决定迁移到 C++ 时,我意识到分配数据结构和释放它们应该放在构造函数和析构函数中。所以我将这些函数更改为构造函数和析构函数。我现在的问题是我需要使用一个参数传递给析构函数以释放分配的数据;该参数不在我自己的代码中,而是 C,我不想弄乱它。
我的问题有两个:
为什么 C++ 一开始就决定不接受析构函数中的参数?和我有哪些选择?(我可以保存指向该参数的指针或以某种方式在我的析构函数中调用该函数,但这似乎不是 C++ 编程的好习惯)
更新:添加一些代码这是我想象中的类(class):
class paru_symbolic/* paru_symbolic*/
{
public:
paru_symbolic ( cholmod_sparse *A, cholmod_common *cc ); // constructor
~paru_symbolic (cholmod_common *cc ); // destructor
// -------------------------------------------------------------------------
// row-form of the input matrix and its permutations
// -----------------------------------------------------------------------
//--- other stuff
...
};
这是我当前的 C 构造函数:
#include "Parallel_LU.hpp"
paru_symbolic *paru_sym_analyse
(
// inputs, not modified
cholmod_sparse *A,
// workspace and parameters
cholmod_common *cc ){
DEBUGLEVEL(0);
...
aParent = (Int*) paru_alloc (m+nf, sizeof(Int),cc);
...
}
和析构函数:
void paru_freesym (paru_symbolic **LUsym_handle,
// workspace and parameters
cholmod_common *cc
){
DEBUGLEVEL (0);
if (LUsym_handle == NULL || *LUsym_handle == NULL){
// nothing to do; caller probably ran out of memory
return;
}
paru_symbolic *LUsym;
LUsym = *LUsym_handle;
Int m, n, anz, nf, rjsize;
...
cholmod_l_free (m+nf, sizeof (Int), LUsym->aParent, cc);
...
cholmod_l_free (1, sizeof (paru_symbolic), LUsym, cc);
*LUsym_handle = NULL;
}
参数 cc 在 SuiteSparse 包中用于跟踪分配和释放数据。它已在 SuiteSparse 包中得到广泛使用,是跟踪内存的有用工具。有人提到谁想要将参数传递给析构函数。这是一个公平的观点,但我们可以将构造函数中的相同参数作为默认值。
析构函数中的参数没有意义,因为当对象超出范围时会自动调用析构函数。您如何向它传递参数?
{
Foo x;
} // `~Foo()` is automatically called here
您可能想要的是将资源存储在您的类中。这是一个带有动态分配指针的不切实际的示例:
struct RAIIPointer
{
Foo* ptr;
// Initialize the resource
RAIIPointer() : ptr{new Foo{/*...*/}}
{
}
RAIIPointer(const RAIIPointer&) = delete;
RAIIPointer& operator=(const RAIIPointer&) = delete;
RAIIPointer(RAIIPointer&&) { /* implement appropriately */ }
RAIIPointer& operator=(RAIIPointer&&) { /* implement appropriately */ }
// Release the resource
~RAIIPointer()
{
delete ptr;
}
};
请注意,在现实世界中,您将使用 std::unique_ptr
,如果您要实现自己的 RAII 资源类,则需要实现正确的复制/移动操作。
我是一名优秀的程序员,十分优秀!