我做了很多c ++(11)但是我倾向于坚持我所知道的。
我正在研究一种队列类型机制,我遇到了一个我确定必须可以解决的问题。
我有:
基类:
typedef shared_ptr<const BaseWorldCommand> ConstBaseWorldCommandPointer;
指针类型
concurrent_queue<ConstBaseWorldCommandPointer>
队列:
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))); }
...
现在我有一个控制类,允许将命令添加到队列中。问题是,我想在队列中添加许多不同的派生类。 到目前为止,我这样做的唯一工作方法是:
protobuf
等
现在,WorldCommandA和WorldCommandB都是BaseWorldCommand的子类。
这里的问题是每次我有一个新的子类时我都需要声明一个方法。
无论如何,我可以创建一个将项添加到队列中的常用方法,而不必每次都声明一个新方法。
现在我试图解决这个问题,但每次我最终只在队列中使用BaseWorldCommand类而不是根据需要的子类。
谢谢,
答案 0 :(得分:4)
我认为你有设计错误。你的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进行长篇讨论和以下指南:
表示函数将存储和共享堆的所有权 使用按值
shared_ptr
参数的对象。