NJU OOP三道好题
T1
任务描述
智能指针是C++标准库提供的一种机制,用于防止内存泄漏,及时回收不再需要的内存。
当我们使用普通的指针变量时,一旦程序变得冗长复杂,难免会出现忘记释放内存的情况,导致可用的内存变少。
如果使用智能指针,那么智能指针内部会维护一个指针指向目标地址,和一个相关联的计数器指针(他们在内存上的地址并无关联,只有逻辑上的联系)。计数器统计持有目标地址的指针数量,一旦计数器为0,那么就可以认为没有任何指针可以访问到该地址,该地址将不再被需要,此时,就可以释放内存。
这样,我们就不需要关心内存的释放,而由智能指针选择在合适的时机释放内存。
本关要求你补全一个伪智能指针类
SmartPointer
,为了简单起见,本关中该智能指针类只能指向动态分配内存的Node
类型的对象,并且一个Node
对象地址只会用于初始化一个智能指针(Node
类型是我们定义的占位类型,一个Node
对象表示一块需要SmartPointer
管理的空间)。它在指针类内部维护两个关键成员变量:
1
2Node* pointer;
int* ref_cnt;Node
类型的指针变量pointer
。- 一个指向整型变量的指针
ref_cnt
,它指向的值*ref_cnt
表示当前拥有pointer
所指向的Node
对象地址的SmartPointer
对象数。
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
class Node;
class SmartPointer
{
Node *pointer;
int *ref_cnt;
public:
SmartPointer()
{
// 空指针
pointer = nullptr;
ref_cnt = nullptr;
}
SmartPointer(Node *p)
{
pointer = p;
ref_cnt = new int(1);
}
// 需要完成的函数
SmartPointer(const SmartPointer &sptr);
void assign(const SmartPointer &sptr); // 指针赋值,将sptr赋值给本指针
~SmartPointer(); // 析构函数,注意:为通过测试样例,需要保证析构函数可以被重复调用
};
class Node
{
int id;
public:
Node(int id)
{
this->id = id;
}
~Node()
{
std::cout << id << ' ';
}
};
SmartPointer::SmartPointer(const SmartPointer &sptr)
{
if (sptr.ref_cnt)
{
(*(sptr.ref_cnt))++;
}
pointer = sptr.pointer;
ref_cnt = sptr.ref_cnt;
}
void SmartPointer::assign(const SmartPointer &sptr)
{
int flag=0;
if (pointer && ref_cnt)
{
(*ref_cnt)--;
if (sptr.ref_cnt)//先加防止自赋值情况
{
(*(sptr.ref_cnt))++;
flag=1;
}
if (*ref_cnt == 0)
{
delete pointer;
pointer=nullptr;
}
}
if (sptr.ref_cnt&&!flag)
{
(*(sptr.ref_cnt))++;
}
pointer = sptr.pointer;
ref_cnt = sptr.ref_cnt;
}
SmartPointer::~SmartPointer()
{
if (pointer)
{
(*ref_cnt)--;
if(*ref_cnt==0) delete pointer, delete ref_cnt;
}
pointer = nullptr;
ref_cnt = nullptr;
}
T2
迭代器是容器类(如数组,链表,队列,栈等)提供的、用于遍历和访问容器内对象的辅助类。在本题中,我们考虑一种简化的迭代器,它为我们自定义的整型数组类提供元素的遍历和访问。
自定义整型数组根据参数创建和维护特定长度的动态整型数组,并且提供迭代器
Iterator
来访问数组arr
中的元素。由于迭代器常与特定类关联,所以我们使用MyArray
的内部类来实现Iterator
1 | // TODO: finish the following class, and override the corresponding operator |
T3
Plant2
类的植物有两个时间节点,time1
和time2
,该类植物从种植开始,生长time1
天之后,每天便可以生产一株新的需要立马种植的完全相同的植物(可以看作每个新植物都会立马被种植),生长time2
天之后,该植物就会死亡。例如某植物在第一天种植,time1=1,time2=2
,那么会在第二天开始生产新植物,在第三天死亡(第三天不能生产新植物)。
1 | Plant2 t(4, 1, 3); //目前已有存活的植物t |
1 | class Plant2 |
- 今天的内容就到这里啦,感谢几位NJU同学的分享~欢迎在评论区继续留言哦O(∩_∩)O