【问题标题】:c++ - How to implement a destructor of an object that uses itself in the constructorc++ - 如何实现在构造函数中使用自身的对象的析构函数
【发布时间】:2018-02-25 06:04:23
【问题描述】:

我正在尝试用 C++ 制作 Thompson 的构造算法(我对该语言有点陌生)。但是我在为我的班级NFiniteAutomaton 实现析构函数时遇到了一些困难。在NFiniteAutomaton 的构造函数的某些部分我有:

NFiniteAutomaton() = default;
NFiniteAutomaton(std::string regex){
    // A lot of code here
    //  ....
    NFiniteAutomaton single_ele;
    single_ele.init_state = new State;
    single_ele.final_state = new State;
    // A lot of code here
    //  ....
}

然后在我的代码的其他部分,我在主NFiniteAutomaton 中创建指向single_ele.init_statesingle_ele.final_state 内容的指针,因为我想重用状态而不是创建具有相同属性的新状态。 结构 State 如下所示:

struct State;
struct Transition {
    State* to;
    std::string symbol;
};

struct State{
    std::vector<Transition> transitions;
};

因此,当我实现 NFiniteAutomaton 的析构函数来删除堆上分配的所有结构时,就会产生我的问题,因为当 single_ele 超出范围时,它会删除所有 State 指针,包括其他指针自动机正在使用(因为析构函数被调用)。我认为的一个解决方案是创建一个方法Clear(),它可以随时删除所有指针,并保留默认的析构函数。有没有办法只使用原始指针来实现这个类的析构函数?

【问题讨论】:

  • 我认为需要有更具体的例子来说明您使用NFiniteAutomaton 所做的事情。对我来说,自动机应该是自包含和完全封装的,从不与其他任何东西共享状态。显然不是这里的情况。

标签: c++ oop c++11 pointers memory-management


【解决方案1】:

我认为的一个解决方案是创建一个方法Clear(),它可以随时删除所有指针,并保留默认析构函数。

可能,但是为什么要创建一个类的用户应该知道的新函数,而不是让析构函数负责释放动态内存呢?我不会那样做的。

在调用NFiniteAutomaton 的析构函数之前,您应该将指针设置为nullptr。在析构函数中,使用delete 表示初始状态和最终状态。

【讨论】:

  • 我不知道删除 nullptr 是否安全。非常感谢。
【解决方案2】:

如果您想让single_ele 对象在构造函数之外持久化,请将其定义为类属性而不是本地对象。析构函数可以进行正常的清理(不需要Clear() 函数),并且对象只会在程序结束时调用析构函数。

class NFIniteAutomaton {
 protected:
  static NFIniteAutomaton single_ele;
  ...
};

【讨论】:

    猜你喜欢
    • 2011-04-06
    • 2019-07-31
    • 1970-01-01
    • 2016-12-28
    • 2013-04-12
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多