gpt4 book ai didi

c++ - 从不透明的 C 结构中公开字段

转载 作者:搜寻专家 更新时间:2023-10-31 01:29:50 24 4
gpt4 key购买 nike

我正在使用一个现有的 C 库(我无法修改),其中一些结构具有不透明的字段,必须通过特定的 setter 和 getter 访问,就像下面的粗略示例(想象 x 是私有(private)的,即使它是用 C 编写的)。

struct CObject {
int x;
};

void setCObjectX(CObject* o, int x) {
o->x = x;
}

int getCObjectX(CObject* o) {
return o->x;
}

我正在编写私有(private)拥有这些类型结构的类,有点像包装器,尽管更复杂。我想以一种方便的方式公开相关字段。起初,我只是在必要时编写 setter 和 getter。但是,我想到了别的东西,我想知道这种方法是否有任何缺点。它使用函数指针 (std::function) 来存储 C setter-getter 对并将它们呈现为就好像直接访问字段而不是函数一样。

这是我编写的用于帮助定义此类“假”字段的通用类:

template<typename T>
struct IndirectField {
void operator=(const T& value) {
setter(value);
}
auto operator()() const -> T {
return *this;
}
operator T() const {
return getter();
}

std::function<void(const T&)> setter;
std::function<T()> getter;
};

通过在C++类中定义一个实例并设置settergetter与相应的C函数来使用:

IndirectField<int> x;
// ...
x.setter = [=](int x) {
setCObjectX(innerObject.get(), x);
};
x.getter = [=]() {
return getCObjectX(innerObject.get());
};

Here is a complete, working code for testing.

使用这种方法有什么缺点吗?它会导致最终的危险行为或其他什么吗?

最佳答案

我在您的解决方案中看到的最大问题是 std::function 对象在 CPPObject 中的每个 IndirectField 实例中占用空间,甚至当 CObject 类型相同时。

您可以通过将函数指针设置为模板参数来解决此问题:

template<typename T,typename R,void setter(R*,T),T getter(R*)>
struct IndirectField {
IndirectField(R *obj) : obj(obj) {
}
void operator=(const T& value) {
setter(obj, value);
}
auto operator()() const -> T {
return *this;
}
operator T() const {
return getter(obj);
}
private:
R *obj;
};

下面是如何使用这个实现:

class CPPObject {
std::unique_ptr<CObject,decltype(&freeCObject)> obj;
public:
CPPObject()
: obj(createCObject(), freeCObject)
, x(obj.get())
, y(obj.get()) {
}
IndirectField<int,CObject,setCObjectX,getCObjectX> x;
IndirectField<double,CObject,setCObjectY,getCObjectY> y;
};

这种方法将两个 std::function 对象换成每个 IndirectField 一个 CObject* 指针。不幸的是,需要存储此指针,因为您无法从模板内的上下文中获取它。

Your modified demo.

关于c++ - 从不透明的 C 结构中公开字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49172907/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com