Skip to content

Commit e427c2b

Browse files
committed
Finish
1 parent fa92ab2 commit e427c2b

File tree

3 files changed

+54
-40
lines changed

3 files changed

+54
-40
lines changed

assign7/main.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <sstream>
99
#include <unordered_map>
1010
#include <vector>
11+
#include <ranges> // std::views
12+
// #include <memory> // smart pointer
1113

1214
#include "unique_ptr.h"
1315

@@ -52,7 +54,15 @@ template <typename T> struct ListNode {
5254
*/
5355
template <typename T> cs106l::unique_ptr<ListNode<T>> create_list(const std::vector<T>& values) {
5456
/* STUDENT TODO: Implement this method */
55-
throw std::runtime_error("Not implemented: createList");
57+
cs106l::unique_ptr<ListNode<T>> head = nullptr;
58+
for (const auto& element : std::views::reverse(values)) {
59+
auto node = cs106l::make_unique<ListNode<T>>(element);
60+
// node->value = element;
61+
node->next = std::move(head);
62+
head = std::move(node);
63+
}
64+
65+
return head;
5666
}
5767

5868
/**

assign7/short_answer.txt

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,21 @@ Unique Pointer
55
--------------
66

77
Q1. List one or two benefits of using RAII to manage memory instead manually calling `new` and `delete`.
8-
A1. TODO
8+
A1. No need to necessary manager memory to avoid forgetting to delete and
9+
causing memory leak.
910

10-
Q2. When implementing move semantics for a `unique_ptr`, for example in the move constructor `unique_ptr(unique_ptr&& other)`, it is essential that we set the underlying pointer of the `other` parameter to `nullptr` before exiting the function. Explain in your own words what problem would arise if we did not.
11-
A2. TODO
11+
Q2. When implementing move semantics for a `unique_ptr`, for example in the
12+
move constructor `unique_ptr(unique_ptr&& other)`, it is essential that we
13+
set the underlying pointer of the `other` parameter to `nullptr` before
14+
exiting the function. Explain in your own words what problem would arise
15+
if we did not.
16+
A2. two pointer -> same one address.
1217

13-
Q3. This method of recursive deallocation through RAII works great for small lists, but may pose a problem for longer lists. Why? Hint: what is the limit for how "deep" a recursive function's call stack can grow?
14-
A3. TODO
18+
Q3. This method of recursive deallocation through RAII works great for
19+
small lists, but may pose a problem for longer lists. Why? Hint:
20+
what is the limit for how "deep" a recursive function's call stack can grow?
21+
A3. windows~1MB linux~8MB macos~8MB
1522

16-
Q4. What does `std::move` do in this context? Why is it safe to use `std::move` and move semantics here?
17-
A4. TODO
23+
Q4. What does `std::move` do in this context? Why is it safe to
24+
use `std::move` and move semantics here?
25+
A4. use std::move -> Object not to use copy, Instead 'move'.

assign7/unique_ptr.h

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,80 +15,73 @@ template <typename T, typename Deleter = std::default_delete<T>> // c++ library
1515
class unique_ptr {
1616
private:
1717
/* STUDENT TODO: What data must a unique_ptr keep track of? */
18-
T* ptr;
18+
T* _ptr;
1919
Deleter deleter;
2020
public:
2121
/**
2222
* @brief Constructs a new `unique_ptr` from the given pointer.
2323
* @param ptr The pointer to manage.
2424
* @note You should avoid using this constructor directly and instead use `make_unique()`.
2525
*/
26-
unique_ptr(T* ptr) {
27-
/* STUDENT TODO: Implement the constructor */
28-
29-
}
26+
unique_ptr(T* ptr) noexcept : _ptr(ptr) {}
3027

3128
/**
3229
* @brief Constructs a new `unique_ptr` from `nullptr`.
3330
*/
34-
unique_ptr(std::nullptr_t) {
35-
/* STUDENT TODO: Implement the nullptr constructor */
36-
return nullptr_t;
37-
}
31+
unique_ptr(std::nullptr_t) : _ptr(nullptr) {}
3832

3933
/**
4034
* @brief Constructs an empty `unique_ptr`.
4135
* @note By default, a `unique_ptr` points to `nullptr`.
4236
*/
43-
unique_ptr() : unique_ptr(nullptr) {
44-
45-
}
37+
unique_ptr() : unique_ptr(nullptr) {}
4638

4739
/**
4840
* @brief Dereferences a `unique_ptr` and returns a reference to the object.
4941
* @return A reference to the object.
5042
*/
51-
T& operator*() {
43+
T& operator*() noexcept {
5244
/* STUDENT TODO: Implement the dereference operator */
53-
return *ptr;
45+
return *_ptr;
5446
}
5547

5648
/**
5749
* @brief Dereferences a `unique_ptr` and returns a const reference to the object.
5850
* @return A const reference to the object.
5951
*/
60-
const T& operator*() const {
52+
const T& operator*() const noexcept {
6153
/* STUDENT TODO: Implement the dereference operator (const) */
62-
54+
return *_ptr;
6355
}
6456

6557
/**
6658
* @brief Returns a pointer to the object managed by the `unique_ptr`.
6759
* @note This allows for accessing the members of the managed object through the `->` operator.
6860
* @return A pointer to the object.
6961
*/
70-
T* operator->() {
62+
T* operator->() noexcept {
7163
/* STUDENT TODO: Implement the arrow operator */
72-
return ptr;
64+
return _ptr;
7365
}
7466

7567
/**
7668
* @brief Returns a const pointer to the object managed by the `unique_ptr`.
7769
* @note This allows for accessing the members of the managed object through the `->` operator.
7870
* @return A const pointer to the object.
7971
*/
80-
const T* operator->() const {
72+
const T* operator->() const noexcept {
8173
/* STUDENT TODO: Implement the arrow operator */
82-
74+
return _ptr;
8375
}
8476

8577
/**
8678
* @brief Returns whether or not the `unique_ptr` is non-null.
8779
* @note This allows us to use a `unique_ptr` inside an if-statement.
8880
* @return `true` if the `unique_ptr` is non-null, `false` otherwise.
8981
*/
90-
operator bool() const {
82+
operator bool() const noexcept {
9183
/* STUDENT TODO: Implement the boolean conversion operator */
84+
return _ptr != nullptr;
9285
}
9386

9487
/** STUDENT TODO: In the space below, do the following:
@@ -98,24 +91,27 @@ class unique_ptr {
9891
* - Implement the move constructor
9992
* - Implement the move assignment operator
10093
*/
101-
~unique_ptr() {
102-
if (ptr) deleter(ptr);
94+
~unique_ptr() noexcept {
95+
deleter(_ptr);
10396
}
10497

105-
unique_ptr(const unique_ptr& other) {
106-
deleter();
107-
}
98+
unique_ptr(const unique_ptr& other) = delete;
10899

109-
unique_ptr& operator=(const unique_ptr& other) {
110-
deleter();
111-
}
100+
unique_ptr& operator=(const unique_ptr& other) = delete;
112101

113102
unique_ptr(unique_ptr&& other) {
114-
std::move()
103+
_ptr = std::move(other._ptr);
104+
other._ptr = nullptr;
115105
}
116106

117-
unique_ptr& operator=(unique_ptr&& other) {
118-
107+
unique_ptr& operator=(unique_ptr&& other) noexcept {
108+
if (this != &other) {
109+
deleter(_ptr);
110+
_ptr = other._ptr;
111+
other._ptr = nullptr;
112+
}
113+
114+
return *this;
119115
}
120116
};
121117

0 commit comments

Comments
 (0)