共享指针集合和常用方法

Shared Pointer Collections and common methods

我做了很多 c++(11),但我倾向于保留我所知道的。

我正在研究一种队列类型的机制,我遇到了一个我确信必须解决的问题。

我有:

基础Class:

BaseWorldCommand

指针类型

typedef shared_ptr<const BaseWorldCommand> ConstBaseWorldCommandPointer;

队列:

concurrent_queue<ConstBaseWorldCommandPointer>

现在我有一个控制 class 允许将命令添加到队列中。问题是,我想向队列中添加许多不同的派生 classes。 到目前为止,我唯一的工作方法是:

void InCommand(const WorldCommandA p_Command) { m_CommandInQueue.push(ConstBaseWorldCommandPointer(new (decltype(p_Command))(p_Command))); }

void InCommand(const WorldCommandB p_Command) { m_CommandInQueue.push(ConstBaseWorldCommandPointer(new (decltype(p_Command))(p_Command))); }

...

等等

现在 WorldCommandA 和 WorldCommandB 都是 BaseWorldCommand 的子 class。

这里的问题是我每次有一个新的子时都需要声明一个方法class。

我是否可以创建一个通用方法来将项目添加到我的队列中,而不必每次都声明一个新方法。

现在我试图解决这个问题,但每次我在队列中只得到一个 BaseWorldCommand class 而不是所需的 subclass。

谢谢,

我认为你有一个设计错误。您的 InCommand 函数不会将它们的参数作为共享指针,这就是为什么您必须复制参数来创建新创建的共享指针可以管理的对象。

这种方法的一个问题是你的BaseWorldCommand因此必须是可复制的,这对于面向对象类(即虚函数)来说通常不是一个好主意).如果你想完成这个,更好的方法是将虚拟 Clone 函数添加到 BaseWorldCommand.

或者,我认为更可取的方法是,您可以让 InCommand 函数采用 std::shared_ptr<InCommand> 并要求客户端创建共享指针(最好使用 std::make_shared ).碰巧,多个功能的问题就会消失,因为你只需要一个这样的功能。

#include <memory>
#include <queue>

class BaseWorldCommand
{
public:
    virtual ~BaseWorldCommand() {}
protected:
    BaseWorldCommand();
private:
    BaseWorldCommand(BaseWorldCommand const&) = delete;
    BaseWorldCommand& operator=(BaseWorldCommand const&) = delete;
};

struct WorldCommandA : BaseWorldCommand {};
struct WorldCommandB : BaseWorldCommand {};

using ConstBaseWorldCommandPointer = std::shared_ptr<BaseWorldCommand const>;

std::queue<ConstBaseWorldCommandPointer> queue;

void InCommand(ConstBaseWorldCommandPointer command)
{
    queue.push(command);
}

int main()
{
    InCommand(std::make_shared<WorldCommandA>());
    InCommand(std::make_shared<WorldCommandB>());
}

另请参阅 GotW #91 Solution: Smart Pointer Parameters 进行详细讨论和以下指南:

Express that a function will store and share ownership of a heap object using a by-value shared_ptr parameter.