物件導向的基石 : class

動態分配記憶體 : new、delete

2022/05/21

Author: 清華資工葉昱揚

今天的課程很hardcore

請繫好安全帶

因為老司機要飆車了

有問題就隨時發問 : D

new、delete

如果我們想寫一個 :

計算25筆資料的平均值的程式,一定會宣告一個大小為25的陣列。

float average[25];

如果你在輸入的時候,不知道最多會有幾筆資料呢,該怎麼辦 ?

  • 隨便亂猜陣列大小嗎 ?
  • 沒用到的記憶體很浪費 ?

你可能會想要這樣寫

int n;
std::cin >> n;
int arr[n];  

但這種定義是不被允許的

所以要怎麼處理資料筆數未知的情況呢 ?

動態記憶體配置(Dynamical Memory Allocation)

  • new : 分配記憶體
  • delete : 釋放記憶體

new運算子會配置變數需要的空間,並回傳地址

因此需要一個指標來儲存地址

這些記憶體會被配置在Heap不會自動清除,需要手動釋放記憶體

釋放new運算子分配的空間。

補充

global 、static variable 放在 data segment

指標變數  =   new 指標的變數型別 [ 記憶體大小 ]   

int *p = new int;
...
delete p;  //用完記得釋放記憶體

只配置空間,但沒有設定初值

int *p = new int(100);
...
delete p;

配置空間,設定初值為100

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

int main() {
	
    
    // 配置sizeof(int)空間,並以指標p1指向該空間
    int *p1 = new int;       
    cout << *p1 << endl;
    delete p1;


    // 配置sizeof(int)空間,並以指標p2指向該空間,同時設立初值為15
    int *p2 = new int(15);  
    cout << *p2 << endl;
    delete p2;
    
    
    // 當然也可以new其他型態
    double *p3 = new double;
    delete p3;

    char *p4 = new char;
    delete p4;
    
    return 0;

}
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

typedef struct student{
    int age;
    double height;
    double weight;
    char address[10];
}student;

int main() {

    student *Peter = new student;
	
    // 印出來會是記憶體殘值,要自己初始化喔 :D
    cout << Peter->age << endl;
    cout << Peter->height << endl;
    cout << Peter->weight << endl;
    cout << Peter->address << endl;
    
    delete Peter;
    
    return 0;
}

也可以new自己寫struct

配置一維陣列 :

  • 假設我們要產生大小為n的一維陣列
int *array = new int[n]; // 中括號[]裡的數字代表陣列大小
    ....
delete []array;          // 記得 delete 要加中括號[],表示釋放連續空間
  • 若想要初始化,使用{ }
int *array = new int[n]{10,20,......,100,......}; 
    ....
delete []array;          // 記得 delete 要加中括號[],表示釋放連續空間

用法跟一般的陣列一樣 !

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

int main() {

    int n;
    cin >> n;

    int *array = new int[n];
    
    for(int i = 0; i < n; i++){
        cin >> array[i];
    }

    for(int i = 0; i < n; i++){
        cout << "array[" << i << "] = " << array[i] << endl;
    }
    
    delete []array;  //記得釋放記憶體


    return 0;
}

arr

arr[0][0]

. . . . . .

arr[0][1]

arr[0][n-1]

arr[1][0]

. . . . . .

arr[1][1]

arr[1][n-1]

arr[m-1][0]

. . . . . .

arr[m-1][1]

arr[m-1][n-1]

T **

T *

T

arr[0]

arr[1]

arr[row-1]

.

.

.

.

.

int **arr = new int*[row];

for(int i = 0 ; i < row ; i++ ){
    arr[i] = new int[col];
}

配置二維陣列

釋放二維陣列

for(int i = 0 ; i < row ; i++ ){
    delete []arr[i];
}
delete []arr;
#include<iostream>
int main(){
    int row,col;
    std::cin >> row >> col;
    
    // memory allocate **arr
    int **arr = new int*[row];
    for(int i = 0 ; i < row ; i++ ){
        arr[i] = new int[col];
    }
    
    for(int i = 0 ; i < row ; i++ ){
        for(int j = 0 ; j < col ; j++){
            std::cin >> arr[i][j];
        }
    }

    for(int i = 0 ; i < row ; i++ ){
        for(int j = 0 ; j < col ; j++){
            std::cout << arr[i][j] << ' ';
        }
        std::cout << std::endl;
    }

    // free **arr
    for(int i = 0; i < row ; i++){
        delete []arr[i];
    }
    delete []arr;

    return 0;
}

用法跟一般的陣列一樣

arr[0][0]

arr[0][1]

arr[1][0]

arr[1][1]

arr[4][0]

arr[4][1]

arr[0][2]

arr[0][3]

arr[2][0]

arr[2][1]

arr[2][2]

arr[2][0]

arr[2][1]

arr[2][2]

arr[3][0]

arr[3][1]

arr[3][2]

arr[3][3]

arr[3][4]

你能做出這種陣列嗎 ?

class

何謂物件 ( object ) ?

IDE依照類別中的宣告,所配置的記憶體空間。

它可以儲存一群資料,能夠對這些資料做自定義的運算處理

把房子想像成一個物件

一間房子由屋頂、前門、牆壁、家具組成

( 資料 )

房子能夠對內部進行布置,換一組沙發、牆壁重新粉刷、屋頂裝上瓦片......

( 運算、處理 )

物件擁有:

資料成員 ( Data member)

成員函式 ( Member function)

何謂類別 ( class ) ?

類別 ( class ) 用來設計物件 ( object),也就是說類別是物件的藍圖。

類別必須使用存取標籤 publicprivate 將成員的權限歸類。

public : 可以由物件取用

private : 僅限類別內部成員存取,外部無法存取

class Object{
private:
// private 的成員只能由內部成員存取

public:
// public 的成員可以由物件取用

};

注意 !!! class的成員預設為private

class Object{
private:
    int x;
    double y;    
public:
    int z;
};
class Object{

    int x;
    double y;    
public:
    int z;
};

兩者的x、y都是private

有點混亂 ? 來看個例子

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

class Box {
public:
      double length;   // Length of a box
      double breadth;  // Breadth of a box
      double height;   // Height of a box
};

int main() {
   Box Box1;        // Declare Box1 of type Box
   Box Box2;        // Declare Box2 of type Box
   double volume = 0.0;     // Store the volume of a box here
 
   // box 1 specification
   Box1.height = 5.0; 
   Box1.length = 6.0; 
   Box1.breadth = 7.0;

   // box 2 specification
   Box2.height = 10.0;
   Box2.length = 12.0;
   Box2.breadth = 13.0;
   
   // volume of box 1
   volume = Box1.height * Box1.length * Box1.breadth;
   cout << "Volume of Box1 : " << volume <<endl;

   // volume of box 2
   volume = Box2.height * Box2.length * Box2.breadth;
   cout << "Volume of Box2 : " << volume <<endl;
   return 0;
}
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

class Box {
public:
    double length;   // Length of a box
    double breadth;  // Breadth of a box
    double height;   // Height of a box
    double volume(){
        return length * breadth * height;
    }
};

int main() {
    Box Box1;        // Declare Box1 of type Box
    Box Box2;        // Declare Box2 of type Box
    double volume = 0.0;     // Store the volume of a box here
 
   // box 1 specification
    Box1.height = 5.0; 
    Box1.length = 6.0; 
    Box1.breadth = 7.0;
    
    // box 2 specification
    Box2.height = 10.0;
    Box2.length = 12.0;
    Box2.breadth = 13.0;
   
    // volume of box 1
    
    //34行可以用member function取代
    //volume = Box1.height * Box1.length * Box1.breadth; 
    cout << "Volume of Box1 : " << Box1.volume() <<endl;

    // volume of box 2
    
    //40行可以用member function取代
    //volume = Box2.height * Box2.length * Box2.breadth; 
    cout << "Volume of Box2 : " << Box2.volume() <<endl;
    
    return 0;
}

把volume寫成member function

function寫在class裡面

只有該類別的物件可以使用

clear

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

class Box {
public:
    double length;   // Length of a box
    double breadth;  // Breadth of a box
    double height;   // Height of a box
    double volume();
};

double Box::volume(){
    return length * breadth * height;
}

記得加上 :: 標示function是哪個類別的成員

或是把member function的implementation

寫在class外面

class Box {
private:
    double length;   // Length of a box
    double breadth;  // Breadth of a box
    double height;   // Height of a box
public:
    double volume(){
        return length * breadth * height;
    }
};

把資料寫進private,更好的保護他們 !

class Box {
public:
    double length;   // Length of a box
    double breadth;  // Breadth of a box
    double height;   // Height of a box
    double volume(){
        return length * breadth * height;
    }
};
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

class Box {
private:
    double length;   // Length of a box
    double breadth;  // Breadth of a box
    double height;   // Height of a box
public:
    double volume(){
        return length*breadth*height;
    }
};

int main() {
 
    Box Box1;        // Declare Box1 of type Box
    Box Box2;        // Declare Box2 of type Box
    
    // box 1 specification
    Box1.height = 5.0; 
    Box1.length = 6.0; 
    Box1.breadth = 7.0;
    cout << Box1.height << ' ' << Box1.length << ' ' << Box1.breadth << endl;
    
    // box 2 specification
    Box2.height = 10.0;
    Box2.length = 12.0;
    Box2.breadth = 13.0;
    cout << Box2.height << ' ' << Box2.length << ' ' << Box2.breadth << endl;
    
    return 0;
}

試著對private的內容做存取

What happened ????

注意 !!!

private的內容只能由public的函式存取

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

class Box {
private:
    double length;   // Length of a box
    double breadth;  // Breadth of a box
    double height;   // Height of a box
public:
    void set(double l,double b,double h){
        length = l;
        breadth = b;
        height = h;
    }
    void print(){
        cout << length << ' ' << breadth << ' ' << height << endl;
    }
    double volume(){
        return length*breadth*height;
    }
};

int main() {
 
    Box Box1;        // Declare Box1 of type Box
    Box Box2;        // Declare Box2 of type Box
    
    // 由物件Box 1 呼叫set函式
    Box1.set(5.0,6.0,7.0);
    Box1.print();
    
    // 由物件Box 2 呼叫set函式
    Box2.set(10.,10.,10.);
    Box2.print();
    
    return 0;
}

可以把12頁的code改寫成這樣

小總結

  • 會不會覺得 class 和 struct 很像 ?

的確 ! 差別在於class預設成員是private,struct預設成員是public。

  • class 和 struct 不要混著使用
  • private的內容不能由外部存取 ! !

constructor 建構子

  • 是個特殊的member function,當物件被宣告時會自動執行constructor
  • 沒有回傳型態
  • 沒有return
  • 命名跟類別的名字一樣
class Box{
public:
    // This is a constructor
    Box(){}
};
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

class Box {
private:
public:
    Box(){
        cout << "object of Box is created" << endl;
    }
};

int main() {
 
    Box Box1;        // Declare Box1 of type Box
    
    return 0;
}

通常用於初始化物件

class Box {
private:
    double length;
    double width;
    double height;
public:
    
    // initializer list 執行速度比下面那個constructor還快
    Box():length(0),width(0),height(0){};
    
    // initialize in body
    Box(){
        length = 0;
        width = 0;
        height = 0;
    }
};

constructor的兩種寫法

class Box {
private:
    double length;
    double width;
    double height;
    
public:
    
    Box():length(0),width(0),height(0){};
    Box(double l,double w,double h):length(l),width(w),height(h){};
    
};

傳參數進constructor

class Box {
private:
    const double z;
    
public:
    Box(){
    	z = 0.0;
    } 
};

當data member為const時

class Box {
private:
    const double z;
    
public:
    Box():z(0.0){}; 
    Box(double Z):z(Z){};
};
class Box {
private:
    const double z;
    
public:
    Box(){
    	z = 0.0;
    } 
    Box(double Z){
        z = Z;
    }
};
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

class Box {
private:
    double length;   // Length of a box
    double breadth;  // Breadth of a box
    double height;   // Height of a box
public:
    
    // line 14,15 are constructors
    Box():length(0),breadth(0),height(0){};
    Box(double l,double b,double h):length(l),breadth(b),height(h){};

    void print(){
        cout << length << ' ' << breadth << ' ' << height << endl;
    }
    
};

int main() {
 
    Box Box1;                     // Declare Box1 with no parameter constructor
    Box Box2(5.0,6.0,7.0);        // Declare Box2 
    
    Box1.print();
    Box2.print();
    
    return 0;
}

可以把15頁的set functionconstructor取代

Destructor

  • 不接受參數
  • 沒有return value
  • 命名跟該類別名稱一樣,前面加上 " ~ "

(1) the function ends
(2) the program ends
(3) a block containing local variables ends
(4) a delete operator is called  

  • 物件 goes out of scope 時自動呼叫

先體驗自動呼叫

class String {
private:
    int x;
    int y;    
public:
    String();   //constructor
    ~String();  //destructor
}; 
String::String(){
    cout << "Construct String" << endl;
}
String::~String(){
    cout << "Destruct String" << endl;    
}
void callString(){
    String str;
}

int main() {
 
    callString();

    return 0;
}
int main() {
 
    String str;
    
    return 0;
}

如果class內有成員是new配置空間,記得用destructor釋放

class String {
private:
    char* s;
    int size;
 
public:
    String(char*); // constructor
    ~String(); // destructor
};
 
String::String(char* c){
    size = strlen(c);
    s = new char[size + 1];
    strcpy(s, c);
}
String::~String(){ 
    delete[] s; 
    cout << "delete successfully !" <<endl; 
}

int main() {
    
    char c[10] = "abcdef"; 
    String str(c);
    
    return 0;
}
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
class String {
private:
    char* s;
    int size;
 
public:
    String(char*); // constructor
    ~String(); // destructor
};
 
String::String(char* c){
    size = strlen(c);
    s = new char[size + 1];
    strcpy(s, c);
}
String::~String(){ 
    delete[] s; 
    cout << "delete successfully !" <<endl; 
}

int main() {
    
    char c[10] = "abcdef"; 
    String *str = new String(c);
    
    return 0;
}

但是不要跟new配置的物件搞混了 !

#include <iostream>
using std::cin;
using std::cout;
using std::endl;
class String {
private:
    char* s;
    int size;
 
public:
    String(char*); // constructor
    ~String(); // destructor
};
 
String::String(char* c){
    size = strlen(c);
    s = new char[size + 1];
    strcpy(s, c);
}
String::~String(){ 
    delete[] s; 
    cout << "delete successfully !" <<endl; 
}

int main() {
    
    char c[10] = "abcdef"; 
    String *str = new String(c);
    delete str;
    
    return 0;
}

自己new出來的空間記得delete  ! !

Dynamic array

是否曾經想過......

int arr[10];

陣列只能存取有限個數字好麻煩Rrrrr

超過10個資料就裝不下了 qqqqqqqq

我想要......

一個酷酷的陣列,它有無限的空間,可以一直塞資料進去

祈禱的你

你的願望 C + + 聽見了

先備知識

  • C + + class
  • new、delete
  • template
  • operator overloading ( optional )

有缺的記得看之前的影片補齊喔 : D

實作目標

1 ) 可以不斷塞資料進去的陣列

2 ) 支援以下功能

3 ) 支援任何形態

  • growth( )            當陣列塞滿時,擴充陣列
  • pushBack( )       把資料從陣列結尾塞進去
  • popBack( )         把資料從陣列結尾捨去
  • size( )                  回傳目前陣列內有幾筆資料
  • reverse( )            把資料排列順序顛倒
template<class T> 
class vector{
private:

    // 指標arr 指向儲存資料的空間
    T *_arr;

    // current 代表目前空間中有幾筆 "可視" 元素
    int _current;
    
    // capacity 代表arr指向的空間 "最多" 能放幾筆資料
    int _capacity;

public:
    
    // constructor 
    vector(); 
    
    // destructor  
    ~vector();  
    
    // make _arr larger to store more data
    void growth();
    
    // push data to the last position of arr 
    void pushBack(T data);      
    
    // throw away the data at the last position 
    void popBack();        
    
    // return current size of arr
    int size();            
    
    // reverse arr
    void reverse();
     
    // overload operator[]
    T& operator [](int index);   
    
};

current

arr 指向記憶體空間

10

template<class T> 
class vector{
private:

    // 指標arr 指向儲存資料的空間
    T *_arr;

    // current 代表目前空間中有幾筆 "可視" 元素
    int _current;
    
    // capacity 代表arr指向的空間 "最多" 能放幾筆資料
    int _capacity;

public:
    
    // constructor 
    vector(); 
    
    // destructor  
    ~vector();  
    
     // make _arr larger to store more data
    void growth();
    
    // push data into the last position of arr 
    void pushBack(T data);      
    
    // throw away the data at the last position 
    void popBack();        
    
    // return current size of arr
    int size();            
    
    // reverse arr
    void reverse();
    
    // overload operator[]
    T& operator [](int index);   
    
};

constructor

template<class T> 
class vector{
private:

    // 指標arr 指向儲存資料的空間
    T *_arr;

    // current 代表目前空間中有幾筆 "可視" 元素
    int _current;
    
    // capacity 代表arr指向的空間 "最多" 能放幾筆資料
    int _capacity;

public:
    
    // constructor 
    vector(); 
    
    // destructor  
    ~vector();  
    
    // push data to the last position of arr 
    void pushBack(T data);      
    
    // throw away the data at the last position 
    void popBack();        
    
    // return current size of arr
    int size();            
    
    // reverse arr
    void reverse();
       
    // overload operator[]
    T& operator [](int index);   
    
};


template<class T>
vector<T>::vector(){

    // TODO : 建構時,_arr只有1個空間存放資料
    
    // TODO : 目前最多容納一筆資料
    
    // TODO : 建構時,還沒有資料在_arr裡面
    
}


template<class T>
vector<T>::~vector(){

    //把配置在heap中的記憶體釋放
    

}


template<class T>
void vector<T>::pushBack(T data){
    /*TODO
    檢查_arr是否已被塞滿。
    若是被塞滿,則將_arr擴充為原本的兩倍
    
    [put your code below] 
    
    
    
    
    
    
    
    
    
    
    
    
    */
    
    _arr[_current] = data;
    _current++;
}


template <class T>
void vector<T>::popBack(){
    // TODO : 把_arr最後一筆data捨去
    
}

template<class T>
int vector<T>::size(){
    // TODO : 回傳目前_arr有幾筆data
}

template<class T>
void vector<T>::reverse(){
    
    /*
    
    TODO  反轉_arr的排序 
    [1,2,3,4,5] -> [5,4,3,2,1]
    
    */
    
    
    
    
}

template<class T>
T& vector<T>::operator[](int index){
    return _arr[index];
}




destructor

template<class T> 
class vector{
private:

    // 指標arr 指向儲存資料的空間
    T *_arr;

    // current 代表目前空間中有幾筆 "可視" 元素
    int _current;
    
    // capacity 代表arr指向的空間 "最多" 能放幾筆資料
    int _capacity;

public:
    
    // constructor 
    vector(); 
    
    // destructor  
    ~vector();  
    
    // push data to the last position of arr 
    void pushBack(T data);      
    
    // throw away the data at the last position 
    void popBack();        
    
    // return current size of arr
    int size();            
    
    // reverse arr
    void reverse();
       
    // overload operator[]
    T& operator [](int index);   
    
};


template<class T>
vector<T>::vector(){

    // TODO : 建構時,_arr只有1個空間存放資料
    
    // TODO : 目前最多容納一筆資料
    
    // TODO : 建構時,還沒有資料在_arr裡面
    
}


template<class T>
vector<T>::~vector(){

    //把配置在heap中的記憶體釋放
    

}


template<class T>
void vector<T>::pushBack(T data){
    /*TODO
    檢查_arr是否已被塞滿。
    若是被塞滿,則將_arr擴充為原本的兩倍
    
    [put your code below] 
    
    
    
    
    
    
    
    
    
    
    
    
    */
    
    _arr[_current] = data;
    _current++;
}


template <class T>
void vector<T>::popBack(){
    // TODO : 把_arr最後一筆data捨去
    
}

template<class T>
int vector<T>::size(){
    // TODO : 回傳目前_arr有幾筆data
}

template<class T>
void vector<T>::reverse(){
    
    /*
    
    TODO  反轉_arr的排序 
    [1,2,3,4,5] -> [5,4,3,2,1]
    
    */
    
    
    
    
}

template<class T>
T& vector<T>::operator[](int index){
    return _arr[index];
}




pushBack

template<class T> 
class vector{
private:

    // 指標arr 指向儲存資料的空間
    T *_arr;

    // current 代表目前空間中有幾筆 "可視" 元素
    int _current;
    
    // capacity 代表arr指向的空間 "最多" 能放幾筆資料
    int _capacity;

public:
    
    // constructor 
    vector(); 
    
    // destructor  
    ~vector();  
    
    // push data to the last position of arr 
    void pushBack(T data);      
    
    // throw away the data at the last position 
    void popBack();        
    
    // return current size of arr
    int size();            
    
    // reverse arr
    void reverse();
       
    // overload operator[]
    T& operator [](int index);   
    
};


template<class T>
vector<T>::vector(){

    // TODO : 建構時,_arr只有1個空間存放資料
    
    // TODO : 目前最多容納一筆資料
    
    // TODO : 建構時,還沒有資料在_arr裡面
    
}


template<class T>
vector<T>::~vector(){

    //把配置在heap中的記憶體釋放
    

}


template<class T>
void vector<T>::pushBack(T data){
    /*TODO
    檢查_arr是否已被塞滿。
    若是被塞滿,則將_arr擴充為原本的兩倍
    
    [put your code below] 
    
    
    
    
    
    
    
    
    
    
    
    
    */
    
    _arr[_current] = data;
    _current++;
}


template <class T>
void vector<T>::popBack(){
    // TODO : 把_arr最後一筆data捨去
    
}

template<class T>
int vector<T>::size(){
    // TODO : 回傳目前_arr有幾筆data
}

template<class T>
void vector<T>::reverse(){
    
    /*
    
    TODO  反轉_arr的排序 
    [1,2,3,4,5] -> [5,4,3,2,1]
    
    */
    
    
    
    
}

template<class T>
T& vector<T>::operator[](int index){
    return _arr[index];
}




popBack

template<class T> 
class vector{
private:

    // 指標arr 指向儲存資料的空間
    T *_arr;

    // current 代表目前空間中有幾筆 "可視" 元素
    int _current;
    
    // capacity 代表arr指向的空間 "最多" 能放幾筆資料
    int _capacity;

public:
    
    // constructor 
    vector(); 
    
    // destructor  
    ~vector();  
    
    // push data to the last position of arr 
    void pushBack(T data);      
    
    // throw away the data at the last position 
    void popBack();        
    
    // return current size of arr
    int size();            
    
    // reverse arr
    void reverse();
       
    // overload operator[]
    T& operator [](int index);   
    
};


template<class T>
vector<T>::vector(){

    // TODO : 建構時,_arr只有1個空間存放資料
    
    // TODO : 目前最多容納一筆資料
    
    // TODO : 建構時,還沒有資料在_arr裡面
    
}


template<class T>
vector<T>::~vector(){

    //把配置在heap中的記憶體釋放
    

}


template<class T>
void vector<T>::pushBack(T data){
    /*TODO
    檢查_arr是否已被塞滿。
    若是被塞滿,則將_arr擴充為原本的兩倍
    
    [put your code below] 
    
    
    
    
    
    
    
    
    
    
    
    
    */
    
    _arr[_current] = data;
    _current++;
}


template <class T>
void vector<T>::popBack(){
    // TODO : 把_arr最後一筆data捨去
    
}

template<class T>
int vector<T>::size(){
    // TODO : 回傳目前_arr有幾筆data
}

template<class T>
void vector<T>::reverse(){
    
    /*
    
    TODO  反轉_arr的排序 
    [1,2,3,4,5] -> [5,4,3,2,1]
    
    */
    
    
    
    
}

template<class T>
T& vector<T>::operator[](int index){
    return _arr[index];
}




size

template<class T> 
class vector{
private:

    // 指標arr 指向儲存資料的空間
    T *_arr;

    // current 代表目前空間中有幾筆 "可視" 元素
    int _current;
    
    // capacity 代表arr指向的空間 "最多" 能放幾筆資料
    int _capacity;

public:
    
    // constructor 
    vector(); 
    
    // destructor  
    ~vector();  
    
    // push data to the last position of arr 
    void pushBack(T data);      
    
    // throw away the data at the last position 
    void popBack();        
    
    // return current size of arr
    int size();            
    
    // reverse arr
    void reverse();
       
    // overload operator[]
    T& operator [](int index);   
    
};


template<class T>
vector<T>::vector(){

    // TODO : 建構時,_arr只有1個空間存放資料
    
    // TODO : 目前最多容納一筆資料
    
    // TODO : 建構時,還沒有資料在_arr裡面
    
}


template<class T>
vector<T>::~vector(){

    //把配置在heap中的記憶體釋放
    

}


template<class T>
void vector<T>::pushBack(T data){
    /*TODO
    檢查_arr是否已被塞滿。
    若是被塞滿,則將_arr擴充為原本的兩倍
    
    [put your code below] 
    
    
    
    
    
    
    
    
    
    
    
    
    */
    
    _arr[_current] = data;
    _current++;
}


template <class T>
void vector<T>::popBack(){
    // TODO : 把_arr最後一筆data捨去
    
}

template<class T>
int vector<T>::size(){
    // TODO : 回傳目前_arr有幾筆data
    
}

template<class T>
void vector<T>::reverse(){
    
    /*
    
    TODO  反轉_arr的排序 
    [1,2,3,4,5] -> [5,4,3,2,1]
    
    */
    
    
    
    
}

template<class T>
T& vector<T>::operator[](int index){
    return _arr[index];
}




reverse

template<class T> 
class vector{
private:

    // 指標arr 指向儲存資料的空間
    T *_arr;

    // current 代表目前空間中有幾筆 "可視" 元素
    int _current;
    
    // capacity 代表arr指向的空間 "最多" 能放幾筆資料
    int _capacity;

public:
    
    // constructor 
    vector(); 
    
    // destructor  
    ~vector();  
    
    // push data to the last position of arr 
    void pushBack(T data);      
    
    // throw away the data at the last position 
    void popBack();        
    
    // return current size of arr
    int size();            
    
    // reverse arr
    void reverse();
       
    // overload operator[]
    T& operator [](int index);   
    
};


template<class T>
vector<T>::vector(){

    // TODO : 建構時,_arr只有1個空間存放資料
    
    // TODO : 目前最多容納一筆資料
    
    // TODO : 建構時,還沒有資料在_arr裡面
    
}


template<class T>
vector<T>::~vector(){

    //把配置在heap中的記憶體釋放
    

}


template<class T>
void vector<T>::pushBack(T data){
    /*TODO
    檢查_arr是否已被塞滿。
    若是被塞滿,則將_arr擴充為原本的兩倍
    
    [put your code below] 
    
    
    
    
    
    
    
    
    
    
    
    
    */
    
    _arr[_current] = data;
    _current++;
}


template <class T>
void vector<T>::popBack(){
    // TODO : 把_arr最後一筆data捨去
    
}

template<class T>
int vector<T>::size(){
    // TODO : 回傳目前_arr有幾筆data
}

template<class T>
void vector<T>::reverse(){
    
    /*
    
    TODO  反轉_arr的排序 
    [1,2,3,4,5] -> [5,4,3,2,1]
    
    */
    
    
    
    
}

template<class T>
T& vector<T>::operator[](int index){
    return _arr[index];
}




overload [ ]

template<class T> 
class vector{
private:

    // 指標arr 指向儲存資料的空間
    T *_arr;

    // current 代表目前空間中有幾筆 "可視" 元素
    int _current;
    
    // capacity 代表arr指向的空間 "最多" 能放幾筆資料
    int _capacity;

public:
    
    // constructor 
    vector(); 
    
    // destructor  
    ~vector();  
    
    // push data to the last position of arr 
    void pushBack(T data);      
    
    // throw away the data at the last position 
    void popBack();        
    
    // return current size of arr
    int size();            
    
    // reverse arr
    void reverse();
       
    // overload operator[]
    T& operator [](int index);   
    
};


template<class T>
vector<T>::vector(){

    // TODO : 建構時,_arr只有1個空間存放資料
    
    // TODO : 目前最多容納一筆資料
    
    // TODO : 建構時,還沒有資料在_arr裡面
    
}


template<class T>
vector<T>::~vector(){

    //把配置在heap中的記憶體釋放
    

}


template<class T>
void vector<T>::pushBack(T data){
    /*TODO
    檢查_arr是否已被塞滿。
    若是被塞滿,則將_arr擴充為原本的兩倍
    
    [put your code below] 
    
    
    
    
    
    
    
    
    
    
    
    
    */
    
    _arr[_current] = data;
    _current++;
}


template <class T>
void vector<T>::popBack(){
    // TODO : 把_arr最後一筆data捨去
    
}

template<class T>
int vector<T>::size(){
    // TODO : 回傳目前_arr有幾筆data
}

template<class T>
void vector<T>::reverse(){
    
    /*
    
    TODO  反轉_arr的排序 
    [1,2,3,4,5] -> [5,4,3,2,1]
    
    */
    
    
    
    
}

template<class T>
T& vector<T>::operator[](int index){
    return _arr[index];
}




template<class T> 
class vector{
private:

    // 指標arr 指向儲存資料的空間
    T *_arr;

    // current 代表目前空間中有幾筆 "可視" 元素
    int _current;
    
    // capacity 代表arr指向的空間 "最多" 能放幾筆資料
    int _capacity;

public:
    
    // constructor 
    vector(); 
    
    // destructor  
    ~vector();  
    
    void growth();

    // push data to the last position of arr 
    void pushBack(T data);      
    
    // throw away the data at the last position 
    void popBack();        
    
    // return current size of arr
    int size();            
    
    // reverse arr
    void reverse();
       
    // overload operator[]
    T& operator [](int index);   
    
};


template<class T>
vector<T>::vector(){

    // TODO : 建構時,_arr只有1個空間存放資料
    _arr = new T[1];    
    // TODO : 目前最多容納一筆資料
    _capacity = 1;
    // TODO : 建構時,還沒有資料在_arr裡面
    _current = 0;
}

template<class T>
vector<T>::~vector(){

    //把配置在heap中的記憶體釋放
    delete [] _arr;

}

template<class T>
void vector<T>::growth(){
    
}

template<class T>
void vector<T>::pushBack(T data){
    /*TODO
    檢查_arr是否已被塞滿。
    若是被塞滿,則將_arr擴充為原本的兩倍
    
    [put your code below] 
    
    
    
    
    
    
    
    
    
    
    
    
    */
    
    _arr[_current] = data;
    _current++;
}


template <class T>
void vector<T>::popBack(){
    // TODO : 把_arr最後一筆data捨去
    
}

template<class T>
int vector<T>::size(){
    // TODO : 回傳目前_arr有幾筆data
}

template<class T>
void vector<T>::reverse(){
    
    /*
    
    TODO  反轉_arr的排序 
    [1,2,3,4,5] -> [5,4,3,2,1]
    
    */
    
    
    
    
}

template<class T>
T& vector<T>::operator[](int index){
    return _arr[index];
}




課後練習

class and new、delete

By Yei Yang

class and new、delete

slides of C++ class and C++ new、delete

  • 321