# 實習課第八次作業 ###### tags: `NTOU CSE C++ Programming` > 教學文件和作業說明文件: https://hackmd.io/@kogiokka/ntou-cse-cpp-nav > 範例程式和範例專案:[Google Drive]( https://drive.google.com/drive/folders/100YvcqccLgY_27mJnubRSuPALrMAghJQ?usp=sharing) 本次作業目標為熟悉 class、constructor 和 destructor(類別、建構子和解構子)。 ## 參考資料 [13.2 — Classes and class members, LEARN C++](https://www.learncpp.com/cpp-tutorial/classes-and-class-members/) ## 題目 實作一個 Stack 類別(儲存 `int` 型別)。Stack 類別應包含下列成員函式(member function): | 函式名稱 | 回傳值型別 | 回傳值意義 | | - | - | - | | `push` | `bool` | 代表**成功或失敗**。| | `pop` | `bool` | 代表**成功或失敗**。| | `isEmpty` | `bool` | 代表 stack **是否**為空 | | `isFull` | `bool` | 代表 stack **是否**滿了 | | `printStack` | `void` | 無回傳值 | 參考範例程式:`class.cpp` ### 需求 #### 一、檔案 1. 使用一個 header file → `stack.h` 2. `main` 函式以及 `Stack` 類別分別放在不同檔案: → `main.cpp` → `stack.cpp` #### 二、程式碼 1. 不可用 global variables 1. 定義 class Stack 1. class Stack 定義放在 `stack.h` 1. class Stack 的 member functions 定義放在 class 外 (`stack.cpp`內) 1. 不再使用的 memory 必須全部釋放(`free` 或 `delete`)。 ### 範例 用陣列(`malloc` 和 pointer)實作 class Stack(第五次版本二),包含下面功能: | 成員函式 | 說明 | | - | - | | constuctor | 一個參數設定 stack 大小(預設值為 10)使用 `malloc` 分配記憶體給陣列(allocate memory)。 | destructor | 使用 `free` 釋放記憶體(deallocate meory)。 | `push` | 回傳**成功或失敗**。| | `pop` | 回傳**成功或失敗**。| | `isEmpty` | 回傳 stack **是否**為空 | | `isFull` | 回傳 stack **是否**滿了 | | `printStack` | 列印出 stack 中儲存的所有資料 | | `stackInitial` | 接受一個參數設定堆疊的大小。如果 Stack 物件中的陣列已經持有記憶體,則分配參數指定的大小的記憶體給它,並且釋放舊的(一樣使用`malloc`和`free`)。回傳**成功或失敗**。| #### 注意事項 在 C++ 程式碼中使用 `malloc` 時請加入`<cstdlib>` 標頭檔。 程式中使用 `malloc` 分配記憶體時 C++ 編譯器可能會報錯。例如: ![](https://i.imgur.com/GOhqOkr.png) 因為 `malloc` 的回傳值是 `void*` 型別,而 C++ 對於型別的轉換有較嚴格的規定。所以請利用C++的`static_cast`將`malloc`回傳值 cast 到變數的型別。範例: ```cpp= #include <cstdlib> int main() { int* x = static_cast<int*>(malloc(10 * sizeof(int))); free(x); return 0; } ``` 參考文件:https://en.cppreference.com/w/cpp/memory/c/malloc #### 參考程式架構 Stack.h ```cpp= // Stack.h #ifndef STACK_H #define STACK_H class Stack { public: Stack(); Stack(int size); ~Stack(); bool push(int value); bool pop(); bool isEmpty(); bool isFull(); void printStack(); bool stackInitial(int size); }; #endif ``` Stack.cpp ```cpp= // Stack.cpp #include "Stack.h" #include <cstdlib> /** * Default Constructor. Allocate memory for the stack. The size of stack is * default to 10. */ Stack::Stack() { /* TODO */ } /** * Constructor. Allocate memory for the stack. * * @param size The initial size of the stack. */ Stack::Stack(int size) { /* TODO */ } /** * Destructor. Deallocate the memory of the stack. */ Stack::~Stack() { /* TODO */ } /** * Member function. Push a value onto the stack. * * @param value The value to be pushed onto the stack. * @return Success or failure. */ bool Stack::push(int value) { /* TODO */ } /** * Member function. Pop the top value from the stack. * * @return Success or failure. */ bool Stack::pop() { /* TODO */ } /** * Member function. Check if the stack is empty. * * @return Whether the stack is empty or not. */ bool Stack::isEmpty() { /* TODO */ } /** * Member function. Check if the stack is full. * * @return Whether the stack is full or not. */ bool Stack::isFull() { /* TODO */ } /** * Member function. Print the whole stack. */ void Stack::printStack() { /* TODO */ } /** * Member function. Reset the stack and give it a new size. * * @param size The new stack size. * @return Success or failure. */ bool Stack::stackInitial(int size) { /* TODO */ } ``` ## 測試案例 ```cpp int main() { Stack s(5); for (int i = 0; i < 5; i++) s.push(i); cout << s.isEmpty(); cout << s.isFull(); for (int i = 0; i < 3; i++) cout << s.pop(); cout << s.isEmpty(); cout << s.isFull(); for (int i = 0; i < 2; i++) cout << s.pop(); cout << s.isEmpty(); cout << s.isFull(); //-------------------------------------- s.stackInitial(10); cout << s.isEmpty(); cout << s.isFull(); for (int i = 0; i < 10; i++) s.push(i); cout << s.isEmpty(); cout << s.isFull(); for (int i = 0; i < 5; i++) cout << s.pop(); cout << s.isEmpty(); cout << s.isFull(); for (int i = 0; i < 5; i++) cout << s.pop(); cout << s.isEmpty(); cout << s.isFull(); //-------------------------------------- s.stackInitial(15); for (int i = 0; i < 15; i++) s.push(i); cout << s.isEmpty(); cout << s.isFull(); for (int i = 0; i < 5; i++) cout << s.pop(); cout << s.isEmpty(); cout << s.isFull(); for (int i = 0; i < 5; i++) cout << s.pop(); cout << s.isEmpty(); cout << s.isFull(); return 0 } ```