作者:曹彩节 | 来源:互联网 | 2023-01-30 15:13
最近,我遇到了一个示例,我的析构函数需要一个参数.
我正在开发一个内部管理内存的C包,并跟踪自己的参数分配和释放.我不想打破这个.
我编写了一个C代码,它初始化了我自己的数据结构并在最后释放它们.当我决定迁移到C++时,我意识到分配数据结构并释放它们应该放在构造函数和析构函数中.所以我将这些函数更改为构造函数和析构函数.我现在的问题是我需要使用一个参数传递给析构函数以释放分配的数据; 该参数不在我自己的代码中,而且是C,我不想搞砸.
我的问题是双重的:
为什么C++首先决定不接受析构函数中的参数?我有什么选择?(我可以保存一个指向该参数的指针,或者以某种方式在我的析构函数中调用该函数,但它似乎不是C++编程的好习惯)
更新:添加一些代码这是我想象的类:
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包中使用,是一个用于跟踪内存的有用工具.有些人提到谁想要将参数传递给析构函数.这是一个公平的观点,但我们可以在构造函数中使用与默认值相同的参数.
1> Vittorio Rom..:
析构函数中的参数没有意义,因为当对象超出范围时会自动调用析构函数.你怎么能把参数传递给那个?
{
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资源类,则需要实现正确的复制/移动操作.
@Aznaveh为什么这看起来不正确?这是围绕C接口构建C++包装器的完美有效方法.也许你应该展示一些示例代码......
@Aznaveh - 那就是我们如何滚动.我们甚至有标准的实用工具,比如`std :: unique_ptr`.资源所有权在C++中不是一个未解决的问题.