Wrapping around old C Structures with smart pointers in C++11 and auto-freeing them

后端 未结 2 1402
南方客
南方客 2021-01-21 23:58

I\'m using Word-Net, an old C library developed by Princeton University back in the nineties. The library is written in C, and only reveals the headers but not its actual implem

2条回答
  •  花落未央
    2021-01-22 00:45

    I know how to solve this problem for unique ownership, using unique_ptr's nifty feature where its managed type becomes Deleter::pointer, instead of T*, if the former type exists.

    Assuming you don't have the definition of Synset, or whatever type SynsetPtr points to, the problem with using a shared_ptr is that it doesn't have the same facility of switching the managed type, and if you create a shared_ptr, the constructor will expect a SynsetPtr*, but your C API functions don't return that type. And I don't know for sure whether using shared_ptr::type> will compile if you don't have the definition of the type that dereferencing a SynsetPtr yields.

    This might work, but I'm not sure.

    std::shared_ptr::type>
    make_findtheinfo_ds(char *searchstr, int pos, int ptr_type, int sense_num)
    {
        return std::shared_ptr::type>
                   (findtheinfo_ds(searchstr, pos, ptr_type, sense_num),
                    free_syns);
    }
    
    std::shared_ptr::type>
    make_traceptrs_ds(SynsetPtr synptr, int ptr_type, int pos, int depth)
    {
        return std::shared_ptr::type>
                   (traceptrs_ds(synptr, ptr_type, pos, depth),
                    free_synset);
    }
    

    Going the unique ownership route, I'd make a couple of factory functions that return unique_ptrs managing SynsetPtrs.

    We need 2 separate deleters for the different kinds of SynsetPtrs

    struct sense_list_del
    {
        using pointer = SynsetPtr;
        void operator()(SynsetPtr p)
        {
            free_syns(p);
        }
    };
    
    struct linked_list_del
    {
        using pointer = SynsetPtr;
        void operator()(SynsetPtr p)
        {
            free_synset(p);
        }
    };
    
    std::unique_ptr
    make_findtheinfo_ds(char *searchstr, int pos, int ptr_type, int sense_num)
    {
        return std::unique_ptr
                   (findtheinfo_ds(searchstr, pos, ptr_type, sense_num));
    }
    
    std::unique_ptr
    make_traceptrs_ds(SynsetPtr synptr, int ptr_type, int pos, int depth)
    {
        return std::unique_ptr
                   (traceptrs_ds(synptr, ptr_type, pos, depth));
    }
    

提交回复
热议问题