为什么不可能破坏一个对象,然后用相同的名称再次实例化它
Why is not possible to destruct an object and then instantiate it again with the same name
我正在为其他人编写的代码创建单元测试,这些代码不能修改。
我试图销毁一个对象,然后从一开始实例化它(所以构造函数将其置于初始条件(
这是我的代码:
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() {}
问题是您正在重新定义已经定义的变量。当你做
state::State_Machine state_machine_test_off;
您基本上将名称state_machine_test_off
锁定在该变量的作用域中。您以后不能执行state::State_Machine state_machine_test_off;
来重置它,因为它试图定义一个新变量,并且名称state_machine_test_off
已经被采用。
要在销毁对象后重新构建它,需要使用placementnew让它再次调用该对象的构造函数。看起来像
new (&state_machine_test_off) state::State_Machine();
现在在state_machine_test_off
的存储器中有一个新的默认构造的state::State_Machine
。
也就是说,如果你只是将对象重新分配给一个默认的构造值,比如,那么所有这些手动调用和未定义行为的机会都会消失
state_machine_test_off = state::State_Machine{};
不能在调用析构函数后的eve之后,在同一级别的作用域中声明另一个同名变量。析构函数不会从作用域中删除旧名称。
为了解决您的问题,我建议添加新的范围级别,因为在任何给定的时间,您似乎只对几行使用state::State_Machine
。
{ state::State_Machine state_machine_test_off;
state_machine_test_off.change_state(States::LOADED);
EXPECT_EQ(States::LOADED,state_machine_test_off.get_state()); }
{ 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
new (&state_machine_test_off) state::State_Machine;
这利用了放置new
,如果您只是正确地使用scope,这是完全不必要的(见上文(。您还必须考虑如果构造函数失败会发生什么,特别是因为仍然需要处理已经构造好的对象,并再次调用其析构函数。
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 函数在可变参数模板的实例化期间不可见
- 为什么我们不在下面给出的代码中使用指针来实例化C++的实体对象?
- 为什么显式模板实例化不会破坏 ODR?
- 需要实例化不同类/对象并在启动时确定的硬件插槽的设计模式
- 为什么显式模板实例化不起作用
- unique_ptr 使用尚未定义的参数进行实例化不会导致错误
- 为什么显式模板实例化不起作用?
- C++标准是否明确允许/禁止实例化不完整类型的 std::函数?
- 为什么不可能实例化原子对
- 模板函数是否以内联方式声明 constexpr,即使实例化不是 constexpr
- 编译的程序是否有可能不包含实例化的模板类
- 模板专用化的实例化不正确
- 为什么很清楚模板函数实例化不会内联
- 为什么这些函数模板中的任何一个都与实例化不匹配?
- 模板实例化不"do inheritance"
- Wykobi -错误:显式实例化不能使用' inline '说明符[-fpermissive]
- 当实例化是可能的,但在c++中不能继承时