如何将工厂方法中的有效指针返回到基于底层操作系统的派生类

Posted

技术标签:

【中文标题】如何将工厂方法中的有效指针返回到基于底层操作系统的派生类【英文标题】:How to return a valid pointer in a factory method to derived class based on underlying OS 【发布时间】:2020-01-29 08:00:31 【问题描述】:

我无法使用工厂方法返回的基类指针调用派生类的私有方法。

当用户在 WIN 上运行时,我想将 unique_ptr 返回给 Cat,当用户在 Linux 上运行时,我想将 unique_ptr 返回给 Dog。

Base.h纯虚类

#include <iostream>
#include <memory>

class Base

public:
    virtual void echo() = 0;
;

Cat.h - Base

的派生类
#include "Base.h"

class Cat : public Base

public:
    void echo();
    void CatPrivateFunction();
;

Cat.cpp

#include "Cat.h"

void Cat::echo()

    std::cout << "In echo()" << std::endl;


void Cat::CatPrivateFunction()

    std::cout << "In CatPrivateFunction()" << std::endl;


Dog.h - Base 的派生类

#include "Base.h"

class Dog

    void echo();
    void DogPrivateFunction();
;

Dog.cpp

#include "Dog.h"

void Dog::echo()

    std::cout << "In echo()" << std::endl;


void Dog::DogPrivateFunction()

    std::cout << "In DogPrivateFunction()" << std::endl;


BaseFactory.h

#ifdef _WIN32
#include "Cat.h"
#elif __linux__
#include "Dog.h"
#endif
#include <memory>

class BaseFactory

public:
    static std::unique_ptr<Base> createBase();
;

BaseFactory.cpp

#include "BaseFactory.h"

std::unique_ptr<Base> BaseFactory::createBase()

#ifdef __linux__
        return std::unique_ptr<Base>(new Dog);
#elif _WIN32
        return std::unique_ptr<Base>(new Cat);;
#endif


在以下脚本中

#include "BaseFactory.h"
int main()

    std::unique_ptr<Base> p = BaseFactory::createBase();
    p->echo();
    p->CatPrivateFunction();
    return 0;

我希望得到以下输出

在 echo() 在 CatPrivateFunction() 中

p-&gt;CatPrivateFunction() 失败,因为 Base.h 没有 CatPrivateFunction() 成员函数。

如何做到这一点?

【问题讨论】:

IIRC 您需要使用 dynamic_cast 并检查 unique_ptr&lt;Base&gt; 是否可以转换为 unique_ptr&lt;Cat&gt; @FMashiro 您不想将unique_ptr&lt;Base&gt; 转换为unique_ptr&lt;Cat&gt;。只是将Base 转换为Cat。有区别。 【参考方案1】:

请阅读upcasting and downcasting

您需要向下转换“指向Base 的指针”为“指向Cat 的指针”。

考虑到你不知道指针所指向的确切类型,你需要使用dynamic_cast并检查结果是否不是空指针:

if (auto cat = dynamic_cast<Cat*>(p.get()))
    cat->CatPrivateFunction();

【讨论】:

【参考方案2】:

如果没有对 Cat 对象的有效指针/引用,您将无法调用 CatPrivateFunction()。由于您只有一个指向Base 的指针,因此您必须使用dynamic_cast 来测试Base 指针是否指向Cat,如果是,那么您可以调用CatPrivateFunction() ,例如:

#include "BaseFactory.h"
#include "Cat.h"

int main()

    std::unique_ptr<Base> p = BaseFactory::createBase();
    p->echo();
    Cat *c = dynamic_cast<Cat*>(p.get());
    if (c)
        c->CatPrivateFunction();
    return 0;

【讨论】:

以上是关于如何将工厂方法中的有效指针返回到基于底层操作系统的派生类的主要内容,如果未能解决你的问题,请参考以下文章

工厂:如何将临时智能指针传递给函数。 C++

Spring中的设计模式:工厂方法模式

如何使用 Mono Project 将 C/C++ 指针传递和保存到 C#,并将它们返回

工厂方法模式在软件系统演化中的应用

工厂方法模式在软件系统演化中的应用

静态工厂的第四个优点是返回对象的类可以根据输入参数的不同而不同。