如何减少大量包装类的实现代码?



我正在开发一个包含一些类的库,我们称它们为C1, C2 and ... Cn。这些类中的每一个都实现一些接口,即I1, I2, ... Im.(n> m)。库中对象之间的关系很复杂,我必须 为我的库用户提供一些 API,以便使用智能指针访问这些对象。

经过一些讨论,我发现将共享指针返回给库用户不是一个好主意,因为在这种情况下,我无法确保可以在库的内存中精确地删除该对象。返回弱指针有同样的问题,因为如果 API 的用户.lock()弱指针并将结果共享指针保留在某个地方,我将再次遇到同样的问题。

我的最后一个想法是,为弱指针公开某种包装器。包装类可以是这样的:

class Wrapper_C1 : public I1
{
std::weak_ptr<C1> mC1;
public:
Wrapper_C1() = delete;
Wrapper_C1(const std::weak_ptr<C1> & c1) : mC1(c1)
{
}
int method1_C1(int x)
{
if (auto sp = mC1.lock())
{
sp->method1_C1(x);
}
else
{
throw std::runtime_error("object C1 is not loaded in the lib.");
}
}
void method2_C1(double y)
{
if (auto sp = mC1.lock())
{
sp->method2_C1(y);
}
else
{
throw std::runtime_error("object C1 is not loaded in the lib.");
}
}
// The same for other methods
};

如您所见,所有这些包装类都共享相同的实现。减少所有这些包装类代码的最佳方法是什么?有没有办法避免重复类似的代码?

如果在包装器中删除继承,则可以执行以下操作来分解所有包装器:

template <typename T>
class Wrapper
{
private:
std::weak_ptr<T> m;
public:
Wrapper() = delete;
Wrapper(const std::weak_ptr<T> & w) : m(w) {}
auto operator -> () /* const */
{
if (auto sp = m.lock())
{
return sp;
}
else
{
throw std::runtime_error("object is not loaded in the lib.");
}
}
};

在不诉诸宏的情况下,你能做的最好的事情就是修复这些重复

if (auto sp = mC1.lock())
{
sp->method1_C1();
}
else
{
throw std::Exception("object C1 is not loaded in the lib.");
}

我所看到的,您可以轻松地将其简化为模板功能,如下所示:

template<class T, class R, class... Args>
R call_or_throw(const std::weak_ptr<T>& ptr, const std::string& error, R (T::*fun)(Args...), Args... args) {
if (auto sp = ptr.lock()) 
{
return std::invoke(fun, *sp, args...);
}
else 
{
throw std::runtime_error(error.c_str());
}
}

比你可以这样使用它:

int method1_C1(int x)
{
return call_or_throw(mC1, "object C1 is not loaded in the lib.", &C1::method1_C1, x);
}
void method2_C1(double y)
{
return call_or_throw(mC1, "object C1 is not loaded in the lib.", &C1::method2_C1, y);
}

您甚至可以从中制作宏

对树/图节点使用智能指针不太理想。树节点析构函数会破坏指向子节点的智能指针,而这些指针反过来调用子节点析构函数,从而导致递归,当树很深或可用堆栈大小较小时,递归可能会溢出堆栈。

另一种设计是拥有一个树类来管理其节点的生存期并使用普通指针 a-lastd::map。并有一个规则,即删除节点会使指向已删除子树的指针和引用无效。

这种设计简单、坚固且在运行时效率最高。

相关内容

  • 没有找到相关文章

最新更新