问题描述
请看下面的代码,您可以将其编译为单个 .cpp 文件,但您应该将基本库代码想象在一个单独的包中:
#include <iostream>
#include <memory>
#include <vector>
// Start of classes defined in a base library shared by many projects
class BaseObject
{
public:
BaseObject() : value(0) {}
BaseObject(int val) : value(val) {}
protected:
int value;
};
class BaseObjectHandler
{
public:
void setVector(std::unique_ptr<std::vector<BaseObject>>&& v)
{
vec = std::move(v);
}
protected:
std::unique_ptr<std::vector<BaseObject>> vec;
};
// End of classes defined in a base library shared by many projects
// Start of specific implementation for project A
class SpecificObject : public BaseObject
{
public:
SpecificObject() : BaseObject(0) {}
};
class SpecificObjectHandler : public BaseObjectHandler
{
public:
void doSomethingOnVector()
{
// Do something on vector
}
};
int main()
{
SpecificObjectHandler handler;
handler.setVector(std::make_unique<std::vector<SpecificObject>>());
handler.doSomethingOnVector();
exit(0);
}
// End of specific implementation for project A
BaseObjectHandler 可以与其派生的处理程序共享一些通用操作,但对特定对象一无所知,因为它驻留在单独的包基础库中。
反过来SpecificObjectHandler驻留在项目A包中,当然知道SpecificObject,需要上面提到的不作用于SpecificObject实例而只依赖BaseObject的常用操作。
由于从 std::vector<SpecificObject>
到 std::vector<BaseObject>
的错误转换,代码显然无法编译。
有没有简单优雅的 C++ 14 方法来解决这个问题?或者您是否建议针对此问题采用完全不同的模式?
我找到了一些类似问题的答案,但我需要更具体的说明。
谢谢。
解决方法
假设您可以编辑基础库代码,您可以将 BaseObjectHandler
定义为模板类
// base_class_library.hpp
template<typename ObjectType>
class BaseObjectHandler
{
public:
void setVector(std::unique_ptr<std::vector<ObjectType>>&& v)
{
vec = std::move(v);
}
protected:
std::unique_ptr<std::vector<ObjectType>> vec;
};
并继承class SpecificObjectHandler : public BaseObjectHandler<SpecificObject>
。现在 SpecificObjectHandler
具有指向 SpecificObject
向量的指针,您的代码将被编译。
当然,它可能会导致与基础库的其他用途发生冲突,但是当您需要旧的(您的)BaseObjectHandler
版本时,您可以将其声明为 BaseObjectHandler<BaseObject>
。作为代价,您将失去将 SpecificObjectHandler
向上转换为通用 BaseObjectHandler
的可能性,但这对您来说可能并不重要。