基类和派生类的 C++ 向量之间的转换

问题描述

请看下面的代码,您可以将其编译为单个 .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 的可能性,但这对您来说可能并不重要。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...