首页 > 解决方案 > 为什么不能破坏一个对象,然后用相同的名称再次实例化它

问题描述

我正在为其他人编写的代码创建单元测试,并且它们不能被修改。

我正在尝试销毁一个对象,然后从头开始实例化它(因此构造函数将其置于初始状态)

这是我的代码:

state::State_Machine state_machine_test_off; 

//Check that OFF is initial state

EXPECT_EQ(States::OFF,state_machine_test_off.get_state());

//Change and check the behaviour from OFF to the other States

state_machine_test_off.change_state(States::LOADED);
EXPECT_EQ(States::LOADED,state_machine_test_off.get_state());
state_machine_test_off.~State_Machine(); //Destructor to iniciate again the process

state::State_Machine state_machine_test_off;
state_machine_test_off.change_state(States::INITIALISED);
EXPECT_NE(States::INITIALISED,state_machine_test_off.get_state());
state_machine_test_off.~State_Machine(); //Destructor to iniciate again the process

然后继续。我不想实例化一个新对象的原因是因为我有一个很大的状态矩阵,它们中的每一个都可以通过 change_state() 移动到某些而不是其他的。

我在互联网上查看了有关析构函数的信息,并且我读到它们可以被显式调用,即使这不是一个很好的做法。

也许有人可以告诉我为什么当我破坏然后再次实例化对象时编译器会失败?

PD:析构函数是默认析构函数

state::State_Machine::~State_Machine() {}

标签: c++destructor

解决方案


问题是您正在重新定义您已经定义的变量。当你这样做

state::State_Machine state_machine_test_off; 

您基本上state_machine_test_off将范围内的名称锁定为该变量。您以后不能state::State_Machine state_machine_test_off;重新设置它,因为它试图定义一个新变量并且名称state_machine_test_off已经被使用。

要在销毁对象后重建对象,您需要使用placement new让它再次调用该对象的构造函数。那看起来像

new (&state_machine_test_off) state::State_Machine();

现在state::State_Machinestate_machine_test_off.


也就是说,如果您只是将对象重新分配给默认构造值,那么所有这些手动调用和未定义行为的机会都会消失,例如

state_machine_test_off = state::State_Machine{};

推荐阅读