2017-05-23 1 views
0

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; 
    } 
} 
를하고있는 클래스의 정적 메서드를 만들 수있는 const 정적에 대한 포인터를 returing하는 기능이있다

unique_ptr 메서드를 BN_value_one의 정적 변수로 반환하기 때문에 반환 값을 소멸시킬 때 세그먼트 화 오류가 발생합니다.

이러한 파괴 또는 더 나은 캡슐화를 방지하는 방법이 있습니까?

+2

'unique_ptr'을 사용하지 않으시겠습니까? –

+0

아마도 'BN_ptr'에 마법의'one()'값을 감싸고 싶다면 일관된 인터페이스를 가질 수 있을까요?함수가 호출 될 때마다 새로운 'one'값을 만들어야하거나 다른 래퍼 클래스를 사용해야 할 것입니다. 여기'unique_ptr'을 사용하는 것이 필수입니까? – Rook

답변

2

openssl 라이브러리를 사용하고 있으므로 으로 BIGNUM 코드를 할당하지 않았기 때문에 BN_free()을 사용할 필요가 없습니다. 자세한 내용은 manpage을 참조하십시오.

따라서 unique_ptr이나 삭제 기가 필요하지 않습니다.

편집 # 1 :

나는 클래스도 BIGNUM 값을 할당 개최 할 수 있음을 참조하십시오. 할당 된 값과 할당되지 않은 값을 구별하는 두 가지 방법이 있습니다. BIGNUM 값.

  1. BigNumber 클래스는 두 개의 다른 생성자를 제공 할 수 있습니다. 할당 상태를 플래그에 저장하고 unique_ptr의 삭제 루틴에서 확인할 수 있습니다.
  2. 다형성을 사용하여 하나의 인터페이스 클래스에서 상속되는 두 개의 다른 클래스를 제공 할 수 있습니다. 한 클래스는 아무 것도하지 않는 Deleter를 구현하고 다른 클래스는 실제로 BN_free()을 호출하는 Deleter를 구현합니다.

편집 # 2 :

지금 당신의 코드가 더 완료됩니다. 자신 만의 더미 자유 함수를 사용하는 const BIGNUM에 대한 포인터를 취하는 부가 생성자를 작성할 수 있습니다. 이 생성자를 사용하는 경우 const_cast을 피해야합니다. 다음과 같아야합니다

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

더미 무료 :

void BN_dummy_free(BIGNUM *a) {} 

이 코드와 함께 작동해야하며 세그먼트 오류에 끝나지 않을 것이다. 그래서 할당 된 할당되지 않은 BIGNUM을 가져갈 수 있습니다.

복사 생성자는 항상 BN_free()을 사용하므로주의해야합니다. BN_dummy_free() 함수 일 수있는 사용한 deleter 함수를 복사해야합니다.

+0

대부분의 경우 클래스가 할당 된 값을 유지합니다 ... 편집했습니다. – nof

+0

일을 분명히하는 데 감사드립니다. 나는 나의 대답을 편집하고 이것이 당신을 도울 것이라는 희망을 품는다. –

관련 문제