如何在类静态成员中引用静态变量?



我试图将一个C模块封装到C++类中。

在 C 实现中,有一个函数将指针重新指向静态常量

const BIGNUM *BN_value_one(void)
{
static const BN_ULONG data_one = 1L;
static const BIGNUM const_one =
{ (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA };
return (&const_one);
}

我试图使它成为类中的静态方法,析构函数执行一些发布操作

class BigNumber
{
struct deleter
{
void operator() (BIGNUM *it)
{
BN_free(it); // The freeing operation provided by origin C library
}
};

using BN_ptr = std::unique_ptr<BIGNUM, deleter>;
/* The OpenSSL BIGNUM pointer */
BN_ptr bn;
public:
BigNumber() : bn(BN_new(), ::BN_free) {}
BigNumber(BigNumber &&other) : bn(std::move(other.bn)) {}
BigNumber(const BigNumber &other) : bn(BN_new(), ::BN_free)
{
::BN_copy(bn.get(), other.bn.get());
}
BigNumber(BIGNUM *src) : bn(src, ::BN_free) {}
static const BigNumber one()
{
static const BigNumber o(const_cast<BIGNUM *>(::BN_value_one()));
return o;
}
}

由于one()方法在BN_value_one中返回一个静态变量的unique_ptr,在破坏返回值时会发生分割错误。

有什么方法可以避免这种破坏,或者更好的封装吗?

当您使用openssl 库时,您不必使用BN_free(),因为您的代码从未分配过带有BN_new()BIGNUM。有关更多说明,请参阅此手册页。

因此,您不需要unique_ptr也不需要删除程序。

编辑#1:

我看到您的类也可以保存分配的BIGNUM值。因此,有两种可能性可以区分已分配和未分配BIGNUM值。

  1. 您的 BigNumber 类可以提供两个不同的构造函数。您可以将分配状态保存在标志中,并在unique_ptr的删除例程中检查它。
  2. 可以使用多态性提供从一个接口类继承的两个不同类。一个类实现一个不执行任何操作的删除器,另一个类实现一个实际调用BN_free()的删除器。

编辑#2:

现在您的代码更加完整。您可以编写一个附加构造函数,该构造函数将指针指向使用自己的虚拟自由函数的 constBIGNUM。如果使用此构造函数,则必须避免const_cast

BigNumber(const BIGNUM *src) : bn(src, ::BN_dummy_free) {}

虚拟免费应如下所示:

void BN_dummy_free(BIGNUM *a) {}

这应该适用于您的代码,并且不会以分段错误告终。因此,您可以采用已分配和未分配的 BIGNUM。

此外,您应该注意复制构造函数,因为它将始终使用BN_free()。您应该复制使用的删除器函数,这可能是BN_dummy_free()函数。

最新更新