【发布时间】:2021-04-22 16:55:02
【问题描述】:
请看下面的代码,你可以将它编译为一个单独的 .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 可以与其派生处理程序共享一些常用操作,但对 SpecificObject 一无所知,因为它驻留在单独的包基库中。
反过来SpecificObjectHandler驻留在项目A包中,当然知道SpecificObject,需要上面提到的不作用于SpecificObject实例而只依赖BaseObject的常用操作。
由于从std::vector<SpecificObject> 到std::vector<BaseObject> 的错误转换,代码显然无法编译。
有没有简单优雅的 C++ 14 方法来解决这个问题?或者你对这个问题提出了一个完全不同的模式?
我找到了一些类似问题的答案,但我需要更具体的说明。
谢谢。
【问题讨论】:
-
std::unique_ptr<std::vector<BaseObject>>与您想要的相反。为了让它工作,你需要一个指向基础对象的指针的向量,或者std::vector<std::unique_ptr<BaseObject>>. -
而不是
setVector函数,我建议您创建一个addObject(或类似的)函数来将一个对象添加到现有向量。 -
不,我想保留一个对象向量,而不是唯一指针。我可以直接传递向量而不是unique_ptr,但问题仍然存在。
-
首先你几乎从不需要一个指向容器的指针,在这种情况下它真的没有意义。其次,您需要阅读object slicing,而
SpecificObject是-aBaseObject,反之则不然。最后,如果你只有一个BaseObject实例,你就不能使用任何类型的多态性,它需要指针或引用才能工作。 -
我认为如果您向我们询问您尝试使用这样的代码解决的实际问题会更好。你为什么需要它?为什么你认为这样的事情是解决这个问题的唯一可能的方法?也许还有其他可能的解决方案?
标签: c++ templates vector base derived