gpt4 book ai didi

c++ - 关于从内存中释放链表的析构函数的逻辑和范围的问题

转载 作者:行者123 更新时间:2023-11-28 06:55:12 25 4
gpt4 key购买 nike

我正在研究一个名为 Stopwatch 的类(class)(因此请忽略下面大部分不完整的地方)。它的界面应该是现实生活中秒表的一个很好的抽象。现在我正在尝试编写析构函数,它将为代表所有圈的链表释放内存。

class Stopwatch
{
typedef enum {UNSTARTED, RUNNING, PAUSED, FINISHED} state;
typedef struct
{
unsigned hours;
unsigned minutes;
unsigned seconds;
} time;
typedef struct
{
unsigned n; // lap number
time t; // lap time
lap* next_ptr;
} lap;

public:
Stopwatch();
~Stopwatch();
void right_button(); // corresponds to start/stop/pause
void left_button(); // corresponds to lap/reset

private:
state cur_state;
lap* first_ptr;

}

Stopwatch::Stopwatch()
{
cur_state = UNSTARTED;
first_ptr = NULL;
}

Stopwatch::~Stopwatch()
{
// Destroy all laps
for (lap* thisptr = first_ptr; thisptr != NULL;)
{
lap* tempptr = thisptr;
thisptr = thisptr.next_ptr;
free (tempptr);
}
cur_state = FINISHED;
}

我实际上还没有尝试编译任何东西,但在继续之前我有几个问题。

(1)我释放链表的逻辑是否正确?我使用的程序是

(i) 将 thisptr 设置为指向第一圈的指针。

(ii) 当 thisptr 不为 NULL 时,存储 thisptr 的拷贝,递增 thisptr,然后释放拷贝指向的内存

这似乎是正确的,但话又说回来,指针对我来说仍然很棘手。

(2) 在使用 free 之后,我是否应该设置一个等于 NULL 的指针?到目前为止,在我看到的所有代码示例中,当编写者想要删除一个变量时,他们只需在其上使用 free 即可。但我正在阅读这个人的说明 http://www.cprogramming.com/tutorial/c/lesson6.html他说之后将其设置为等于 NULL。一直觉得他的教程不错

(3) 当我在析构函数中引用 lap* 时,是否需要使用 namespace 运算符?即,我是否需要编写 Stopwatch::lap* 而不是 lap* ???我什至在类中的正确位置声明了 lap 结构吗?

最佳答案

释放后将指针设置为 NULL 是没有必要的。可以推荐这样,如果在 free() 之后有使用,代码将(应该...)立即崩溃并且更容易调试。然而在 C++ 中你不应该需要它,因为你应该 RAII 并且从不拥有​​拥有所有权的原始指针。

另请注意,在 C++ 中,您使用 newdelete,而不是 mallocfree

你的 for 循环不是很地道,它看起来更像是一个 while 循环,所以这样更可读:

lap* thisptr = first_ptr;
while(thisptr)
{
lap* tempptr = thisptr;
thisptr = thisptr.next_ptr;
free (tempptr);
}

逻辑似乎没问题。但是,如果这不是一些作业项目,您应该更改一些内容:

1) 使用标准容器。如果可以使用 vector ,则使用它。如果您的代码不适合 vector ,请重新考虑使用 vector ;-)如果您以这种方式更改代码,则不需要析构函数:

class Stopwatch
{
...
typedef struct
{
unsigned n; // lap number
time t; // lap time
} lap;

...

private:
...
std::list<lap> laps; // Could you use vector?

}

请注意,在 C++ 中,您通常以这种方式声明结构:

    struct lap
{
unsigned n; // lap number
time t; // lap time
};

您可以在 Stopwatch 类中使用 lap 来引用它。

2) C++11 提供日期/时间工具:

class Stopwatch
{
...
typedef std::chrono::system_clock::time_point time;
...
}

3) 在你的构造函数中使用初始化列表是个好习惯:

Stopwatch::Stopwatch()
: cur_state(UNSTARTED)
{
}

对于 C++11 中的简单情况,您甚至不需要构造函数:

class Stopwatch
{
...
private:
state cur_state = UNSTARTED;
...
}

另请注意,在析构函数中将状态更改为 FINISHED 几乎没有用,因为对象已被...销毁。

关于c++ - 关于从内存中释放链表的析构函数的逻辑和范围的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23277114/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com