从抽象基类型的unique_ptr中获取Derieved类

时间:2018-06-09 02:30:11

标签: c++ c++11 inheritance design-patterns

我有一个案例,我想为空间搜索结构公开一个干净的API。 现在我很方便地代表了这个玩具示例中的更大案例。 这里有两个抽象基类ToySmallToyBig,派生类型ToySmall的实例是在实例派生类型{{1}的returnSmall方法中创建的}}

以下是ToyInterface.h的内容

ToyBig

我有#include <iostream> #include <memory> class ToySmall { public: ToySmall() {} virtual void toyMethod() const = 0; }; class ToyBig { public: ToyBig() {} virtual std::unique_ptr<ToySmall> returnSmall() = 0; }; 的返回类型为returnSmall,以便返回共变体类型,因为每个派生类型的std::unique_ptr<ToySmall>都会返回ToyBig的不同派生类型。

但是在实现这些接口并按照我的意图使用它们时,我在下面的文件中遇到ToySmall的具体实例时遇到了问题。我在下面的源代码中包含了这些错误。

ToySmallImpl

由于#include <iostream> #include "ToyInterfaces.h" class ToySmallImpl : public ToySmall { public: ToySmallImpl() : ToySmall() {} void toyMethod() const override { std::cout << "All Good!!" << std::endl; } }; class ToyBigImpl : public ToyBig { public: ToyBigImpl() : ToyBig() {} std::unique_ptr<ToySmall> returnSmall() override { ToySmall* small; ToySmallImpl smallImpl; small = &smallImpl; return std::unique_ptr<ToySmall>(small); } }; int main() { ToyBigImpl bigImpl; std::unique_ptr<ToySmall> toySmall = bigImpl.returnSmall(); // ToySmallImpl toySmallImpl = *toySmall; // Error : error: conversion from ‘ToySmall’ to non-scalar type ‘ToySmallImpl’ requested ToySmallImpl toySmallImpl = static_cast<ToySmallImpl>(*toySmall); // Error : no matching function for call to ‘ToySmallImpl::ToySmallImpl(ToySmall&)’ toySmallImpl.toyMethod(); } 类要从我拥有的接口扩展,并且也可以由其他开发人员实现,我不想要复制构造函数或Impl运算符,正如大多数其他解决方案一样如果它只适合我,我很高兴让这个工作,但我可以。但是,我希望它是干净的,以便我可以将解决方案作为API的其他用户的指南。

我想知道是否有其他人有类似案例并且可以指出我可能的解决方案,=我可以创建main的实例并使用它。< / p>

2 个答案:

答案 0 :(得分:1)

您的代码更像Proxy Design Pattern.尝试此操作:

class ToyBigImpl : public ToyBig
{
public:
    ToyBigImpl()
        : ToyBig()
    {}

    std::unique_ptr<ToySmall> returnSmall() override
    {
        std::unique_ptr<ToySmall> small = std::make_unique<ToySmallImpl>();
        return std::move(small);
    }
};

int main(int argc, char** argv)
{
    ToyBigImpl bigImpl;
    std::unique_ptr<ToySmall> toySmall = bigImpl.returnSmall();

    ToySmallImpl toySmallImpl = *(reinterpret_cast<ToySmallImpl*>(toySmall.get()));

    toySmallImpl.toyMethod();                                                                         
    return 0;
}

答案 1 :(得分:1)

使用:

std::unique_ptr<ToySmall> returnSmall() override
{
    ToySmall* small;
    ToySmallImpl smallImpl;
    small = &smallImpl;
    return std::unique_ptr<ToySmall>(small); // Return dangling pointer
}

你返回悬空指针,你可以这样做:

std::unique_ptr<ToySmall> returnSmall() override
{
    return std::make_unique<ToySmallImpl>();
}

然后,对于多态类型,&#34; right&#34; cast是dynamis_cast

std::unique_ptr<ToySmall> toySmall =  bigImpl.returnSmall();

auto& toySmallImpl = dynamic_cast<ToySmallImpl&>(*toySmall);
toySmallImpl.toyMethod();