代码之家  ›  专栏  ›  技术社区  ›  Post Self

自定义引用类型[已关闭]

  •  0
  • Post Self  · 技术社区  · 7 年前

    我正在写一个C-API的包装器。

    (i) 让 capi_array_data capi_get_array(void) 是一个包含在这个库中的函数,返回一个结构,该结构包含由所述API管理的堆分配数组的元数据。它看起来像 struct capi_get_array { size_t length; int* arr }; (使用 int (为了简单起见)

    malloc , new std::vector 然后必须在 void capi_register_array(int*) .

    MyArrayWrapper ,使用STL容器的解剖结构管理这样的数组,支持 operator[] , begin , back 在(i)中,这个包装器不会拥有数据,但在(ii)中,它会拥有数据。我现在的问题是,我是否应该

    std::initializer_list (或可变模板)或 int*

    (b) 有单独的类命名为 MyArrayWrapperRef ,第一次处理(i)和第二次处理(ii);

    (c) 最好有语法 MyArrayWrapper& 对于(i)和 MyArrayWrapper公司

    对于(a),可能会出现混乱,因为一个类做两件事,这打破了单一责任原则。对于“复制构造师是否进行了深度或浅层复制?”这样的问题,答案并不明显,需要进一步的文档。

    MyArrayWrapper公司 , MyArrayWrapperRef公司 MyArrayWrapperRef& . 他们有什么不同?那怎么办 const MyArrayWrapperConstRef 再次导致混乱。

    (c) 是最佳的,似乎与其他类自然,但我不知道如何使它工作。我可以把它包起来 capi_get_array 返回 ,但我必须把参考资料的来源保存在某个地方,对吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   463035818_is_not_an_ai    7 年前

    对于(a)可能会出现混淆,因为一个类做两件事, 打破了单一责任原则。

    struct arr_data {
        int* a;
        unsigned size;
    };
    arr_data get_arr(){
        arr_data ret;
        ret.size = 5;
        ret.a = new int[ret.size];
        return ret;
    }
    void reg_arr(arr_data x){
        static arr_data store = x;
    }
    

    那么一个简单的包装器可以如下所示:

    struct wrapper {
        std::shared_ptr<arr_data> data;
        // implement container-like interface
    };
    
    wrapper make_non_owning_wrapper() { 
        auto res = new arr_data();
        *res = get_arr();
        return { std::shared_ptr<arr_data>(res,[](arr_data* x){
                std::cout << "delete x only\n";
                delete x;
        }) };
    }
    
    wrapper make_owning_wrapper() {
        auto res = new arr_data();
        res->size = 5;
        res->a = new int[res->size];
        return { std::shared_ptr<arr_data>(res,[](arr_data* x){
            std::cout << "delete both\n";
            delete[] x->a;
            delete x;
        })};
    }
    
    int main(){
        auto v = make_owning_wrapper();
        auto w = make_non_owning_wrapper();
        auto z = v;
    }
    

    使用共享指针,您可以选择a)清理时执行的操作,以及b)复制 wrapper 不会引起很大的混乱;)。

    推荐文章