简体   繁体   English

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

[英]How to refering a static variable in a class static member?

I'm tring to encapsulate a C module into C++ classes. 我正试图将C模块封装到C ++类中。

In the C implementation there is a function returing a pointer to a static const 在C实现中,有一个函数可以重载指向静态const的指针

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);
}

I'm tring to make it a static method in a class with a destructor doing some releasing actions 我正在尝试使其在带有析构函数的类中进行一些释放操作的静态方法

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;
    }
}

Since the one() method returning a unique_ptr to a static variable in BN_value_one , it will occurs a segmentation fault when destructing the returned value. 由于one()方法将unique_ptr返回到BN_value_one的静态变量,因此在销毁返回值时会发生分段错误。

Is there any way the avoid such destruction, or any better encapsulation? 有什么办法可以避免这种破坏或更好的封装?

As you're using the openssl library you don't have to use BN_free() because your code never allocated a BIGNUM with BN_new() . 当你正在使用OpenSSL库,你不必使用BN_free()因为你的代码永远不会分配BIGNUMBN_new() For more explanation see this manpage . 有关更多说明,请参见此联机帮助页

So you don't need the unique_ptr nor the deleter. 因此,您不需要unique_ptr或删除器。

Edit #1: 编辑#1:

I see that your class can also hold allocated BIGNUM values. 我看到您的课程也可以保存分配的BIGNUM值。 So there are two possibilities to distinguish between allocated and not allocated BIGNUM values. 因此,有两种可能性可以区分已分配和未分配的BIGNUM值。

  1. Your BigNumber class could provide two different constructors. 您的BigNumber类可以提供两个不同的构造函数。 You can save the state of allocation in a flag and check it in the deleting routine of the unique_ptr . 您可以将分配状态保存在标志中,并在unique_ptr的删除例程中进行检查。
  2. You could use polymorphism to provide two different classes that inherits from one interface class. 您可以使用多态来提供从一个接口类继承的两个不同的类。 The one class implements a deleter that does nothing and the other one implements one that actually call BN_free() . 一类实现一个不执行任何操作的删除程序,另一类实现一个实际调用BN_free()的删除程序。

Edit #2: 编辑#2:

Now your code is more complete. 现在,您的代码更加完整。 You could write an addional constructor that takes a pointer to a const BIGNUM that uses an own dummy free function. 您可以编写一个额外的构造函数,该构造函数使用指向使用自己的伪自由函数的const BIGNUM的指针。 You have to avoid the const_cast if you use this constructor. 如果使用此构造函数,则必须避免const_cast

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

The dummy free should look like this: 自由假人应如下所示:

void BN_dummy_free(BIGNUM *a) {}

That should work with your code and will not end in a segmentation fault. 那应该与您的代码一起使用,并且不会以分段错误结束。 So you could take allocated and non allocated BIGNUMs. 因此,您可以使用已分配和未分配的BIGNUM。

Also you should take care at your copy constructor, because it will always use BN_free() . 另外,您还应注意复制构造函数,因为它将始终使用BN_free() You should copy the used deleter function, which could may be the BN_dummy_free() function. 您应该复制使用的删除器函数,该函数可能是BN_dummy_free()函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM