- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在研究一个名为 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++ 中,您使用 new
和 delete
,而不是 malloc
和 free
。
你的 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/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!