首页 > 解决方案 > 有没有办法在不改变指针本身的值的情况下替换由 shared_ptr 指向的对象?

问题描述

在我的代码中,我有一个应用程序,其中包含一个状态管理器和一个应用程序可能状态的列表。在创建不同的状态时,我想向它传递一个命令列表(遵循命令模式),在执行时,将状态管理器的当前状态更改为创建命令对象时指定的状态。

这意味着在创建状态对象时,我传入一个shared_ptr<Command>s 列表,所有这些都包含 a shared_ptr<ApplicationState>,其中一个命令指针将包含一个指向ApplicationState作为构造函数参数传递给该列表的对象的指针。

为了实现这一点,我尝试通过首先使用 为对象shared_ptr<Command>分配空间来创建 s列表,因此创建了 s 的指针,并通过其默认构造函数初始化了状态对象。然后我可以将命令列表传递给状态构造函数,使用已经创建的. 现在该对象包含一个命令列表,其中一个包含一个指向相同的指针,其中包含由参数化构造函数初始化的所有数据。ApplicationStatestd::allocate_shared<ApplicationState>()ApplicationStatereset(new ApplicationState(commandstochangestate, otherargs))shared_ptr<ApplicationState>ApplicationStateApplicationState

至少这是计划,但显然我使用的功能并没有像我想象的那样工作。reset()在分配ApplicationState的对象上使用该函数后,Command对象仍然指向空对象,并在执行时抛出异常,因为它们试图使用未初始化的成员。然而,完成的状态对象确实与空的状态对象并存。

实际代码如下所示:

// Create allocators for allocating the state objects

std::allocator<MainState> allocator_main;
std::allocator<ExtraState> allocator_extra;

// Allocate pointers for _states
// The states allocated here are of type MainState and ExtraState, dummy classes for now, but they
// both inherit from the class ApplicationState

_states[size_t(State::main)] = std::allocate_shared<MainState>(allocator_main);
_states[size_t(State::extra)] = std::allocate_shared<ExtraState>(allocator_extra);

// List of command objects is created

std::shared_ptr<std::shared_ptr<ICommand>[size_t(State::count)]> changestatecommands( new 
    std::shared_ptr<ICommand>[size_t(State::count)], 
    std::default_delete<std::shared_ptr<ICommand>[]>()
);

// Here the command objects are created, the std::shared_pointer to the state objects are passed in
// as the second argument. _states is an array of type 
// std::shared_ptr<ApplicationState>[State::count] (State::count is 2)

changestatecommands[size_t(State::main)] = std::make_shared<StCmdActivate>(_statemanager, _states[size_t(State::main)]);  // StCmdActivate is a child class of Command that sends the specified state to the statemanager, which changes its active state to that state
changestatecommands[size_t(State::extra)] = std::make_shared<StCmdActivate>(_statemanager, _states[size_t(State::extra)]);

// Here I want to replace the objects pointed to by the pointers held by the command objects,
// but instead new pointers are created, and the command objects still point to the empty shells

_states[size_t(State::main)].reset(new MainState(changestatecommands, _window->inputhandler()));
_states[size_t(State::extra)].reset(new ExtraState(changestatecommands, _window->inputhandler()));

// When the command to change the current state to State::main is executed, an exception is thrown 
// because it passes an empty state object to the statemanager

changestatecommands[size_t(State::main)]->execute();

我正在尝试做的事情有可能吗?如果是这样,我该如何正确地做到这一点?如果不是,我应该如何以另一种方式实现相同的功能?我希望每个状态对象都保存所有改变状态的命令。

标签: c++shared-ptr

解决方案


推荐阅读