C++;使用类模板的循环依赖-如何重构? 我处理C++中的循环依赖问题。< /P>
情况如下:C++;使用类模板的循环依赖-如何重构? 我处理C++中的循环依赖问题。< /P>,c++,templates,circular-dependency,extensible,C++,Templates,Circular Dependency,Extensible,情况如下: libA.so: - Body.cpp - Header.cpp - DataObject.cpp - DataObject::read(boost::asio::streambuf* data) { boost::asio::streambuf data; .... body = (new DataConverter<Body>)->convert(&
libA.so:
- Body.cpp
- Header.cpp
- DataObject.cpp
- DataObject::read(boost::asio::streambuf* data)
{
boost::asio::streambuf data;
....
body = (new DataConverter<Body>)->convert(&data);
header = (new DataConverter<Header>)->convert(&data);
}
libB.so:
- DataConverter.cpp
-> DataConverter<T>
-> T* DataConverter<T>::convert(boost::asio::streambuf* data)
libA.so <-> libB.so
libA.so:
-Body.cpp
-Header.cpp
-DataObject.cpp
-数据对象::读取(boost::asio::streambuf*数据)
{
boost::asio::streambuf数据;
....
body=(新数据转换器)->convert(&data);
header=(新数据转换器)->convert(&data);
}
libB.so:
-DataConverter.cpp
->数据转换器
->T*DataConverter::convert(boost::asio::streambuf*数据)
libA.so libB.so
存在循环依赖关系,因为libA使用libB中的Converter类,libB现在需要了解需要转换的libA的对象类型,因为DataConverter::convert返回一个Body或Header对象
我曾想过用前瞻性声明来解决这个问题,但对我来说,这似乎不是最干净的解决方案。总之,我的计划是提供一个可扩展的DataConverter解决方案
你们认为什么是最佳实践?也欢迎完全不同的设计:)
最好的,
Sebastian您可能希望创建定义接口的抽象基类,并隐藏彼此之间的实现(派生类)。如果您需要类模板
DataConverter
,则这不能是任何编译库的一部分。它必须通过包含文件提供。一旦您将DataConverter
代码放入一个标头中,供libA
和libB
使用,您的循环依赖性就会消失。您的设计似乎有缺陷。如果名为A和B的两个库相互依赖,则意味着它们必须始终一起装运。如果它们必须始终一起装运,这意味着它们在逻辑上是同一接口的一部分。这意味着事实上,你只有一个图书馆
没有足够的信息说明什么是最佳解决方案,但以下是一些提示:
DataConverter
作为一个完全通用的实现,将在编译时使用适当的类型在libA.so中实例化。这是一个典型的c++-ish解决方案。来自libA(或其他)的“可转换”类型必须满足一些convertable
概念,DataConverter
的完全模板化实现将使用这些概念Boost.Serialization
。然而,这很难实现,也很容易打破好的-如何定义一个AbstractConverter工厂,它实际返回指定模板化目标格式的具体实现。但这将如何解决我的依赖性问题呢?定义一个包含转换器所需的所有方法(抽象)的抽象类。您可以在头文件中执行此操作。在liba.so和libb.so的源中包括此标头。libb中的转换器(实际上,很可能)派生自抽象类。libb包含两个返回转换器的工厂方法,这些工厂方法在liba中声明为extern。因此,libb知道liba,但liba现在不知道libb。这看起来像是内存泄漏——你几乎肯定想要
DataConverter().convert(&data)
,没有new
(除非convert
以delete this
结尾,但那会很可怕)。这是比其他任何东西都更伪的代码:)