我正在使用由几种不同类型(属性、父级、子级等)组成的模型。每种类型都与一组来自C API的函数相关联。例如:
Type "Properties":
char* getName(PropertiesHandle);
char* getDescription(PropertiesHandle);
Type "Parent"
PropertiesHandle getProperties(ParentHandle);
ChildHanlde getFirstChild(ParentHandle);
Type "Child"
PropertiesHandle getProperties(ChildHandle);
ParentHanlde getParent(ChildHandle);
ChildHandle getNextChild(ChildHandle);
我已经为这个C API库创建了一组C++接口,如下所示:
class IProperties
{
public:
virtual std::string getName() = 0;
virtual std::string getDescription() = 0;
};
class IParent
{
public:
virtual std::shared_ptr<IProperties> getProperties() = 0;
virtual std::shared_ptr<IChild> getFirstChild() = 0;
};
class IChild
{
public:
virtual std::shared_ptr<IProperties> getProperties() = 0;
virtual std::shared_ptr<IParent> getParent() = 0;
virtual std::shared_ptr<IChild> getNextChild() = 0;
};
我将通过Properties、Parent和Child这些类来实现这些接口。因此,Child实例将通过其构造函数获取其特定的ChildHandle,并且其getParent函数将会像这样:
std::shared_ptr<IParent> getParent()
{
// get the parent handle and wrap it in a Parent object
return std::shared_ptr<IParent>(new Parent(_c_api->getParent(_handle)));
}
你认为我在这里返回一个shared_ptr是否合理?我不能使用std::unique_ptr,因为Google Mock要求模拟方法的参数和返回值可复制。我通过Google Mock在我的测试中模拟这些接口。
我也在考虑未来可能会进行的优化,这可能会导致循环引用的可能性。如果使用缓存来避免对C API的多次调用(例如,不需要子对象多次建立父对象),再加上Child构造函数需要其Parent,则可能会导致循环引用。这将需要使用weak_ptr来更改接口和大量代码...
getParent()
正在交接新的外观实例。我唯一担心的是Parent
相对于底层对象的生命周期。理想情况下,底层对象也应该被引用计数,并且创建外观会保留它。否则,底层对象的生命周期可能比外观还要短。 - markounique_ptr
的唯一理由是Google Mock无法与其配合使用。这是一个糟糕的论据。测试框架不应该限制你设计的基本方面(尽管模拟总会在某种程度上做到这一点)。 - Konrad Rudolph