如何围绕C'类'泛化此C ++包装器?

我正在围绕C库编写C ++包装器。这是我的策略示例。

    // header file
    class LibrdfUri { // wrapper around librdf.h librdf_uri* 

        /*
         * If the deleter of std::unique_ptr is an empty
         * class then it can do some optimizations and
         * not actually store the deleter object.
         * Otherwise it has to accommodate extra space for
         * the deleter, which is unnecessary
         *  https://stackoverflow.com/questions/61969200/what-is-the-purpose-of-wrapping-this-private-deleter-function-in-a-struct/61969274#61969274
         */
        struct deleter {
            // turns deleter into a functor. For passing on to unique_ptr
            void operator()(librdf_uri *ptr);
        };
        // automate management of librdf_uri* lifetime
        std::unique_ptr<librdf_uri, deleter> librdf_uri_;

    public:
        LibrdfUri() = default;

        explicit LibrdfUri(const std::string& uri); // construct from string

        librdf_uri *get(); // returns the underlying raw pointer

    };
    // implementation
    void LibrdfUri::deleter::operator()(librdf_uri *ptr) {
        librdf_free_uri(ptr); // this is the C library function for destruction of librdf_uri
    }

    LibrdfUri::LibrdfUri(const std::string &uri) {
        // create pointer to underlying C library 'object'
        librdf_uri_ = std::unique_ptr<librdf_uri, deleter>(
                librdf_new_uri(World::getWorld(), (const unsigned char *) uri.c_str()) // World::getWorld is static. Returns a pointer required by librdf_new_uri
        );
    }

    librdf_uri *LibrdfUri::get() {
        return librdf_uri_.get();
    }

// and is used like so:
LibrdfUri uri("http://uri.com");
librdf_uri* curi = uri.get(); // when needed

This works for the single type librdf_uri* which is a part of the underlying library however I have lots of these. My question is double barrelled. The first part concerns the best general strategy for generalizing this wrapper to other classes while the second is concerns the implementation of that strategy.

关于第一部分,这是我的想法:  1.我可以像在这里一样手动实现每个类。这可能是最简单,最不优雅的。但是,它仍然可能是我最好的选择。但是,由于我编写的每个CWrapper本质上都具有相同的结构,因此涉及少量的代码重复。更不用说我是否需要更改某些内容,那么我将必须分别完成每个课程。  2.使用基类(抽象?)  3.使用模板

我的问题的第二部分基本上是:如果我实施选项2或3(我认为甚至可能只是一个选项),我将如何做?

这是我在想的一个(严重损坏的)版本:

template<class LibrdfType>
class CWrapper {

    struct deleter { ; //?
        void operator()(LibrdfType *ptr) {
            // ??
        };
    }

    std::unique_ptr<LibrdfType, deleter> ptr;

public:
    CWrapper() = default;

    LibrdfType *get() {
        ptr.get();
    };

};

Then, LibrdfUri and any other C class I need to wrap, would just subclass CWrapper

关于选项2和3,我怀疑这可能只是一个选项。

评论