1. 程式人生 > >C++ 動態物件陣列的知識總結

C++ 動態物件陣列的知識總結

預設建構函式

    首先,我們來看一下是什麼是預設建構函式,如下面一段程式碼:

#include<iostream>
#include<math.h>
using namespace std;
class Point
{
    double x, y;
public:
    void print();
    Point(double a=0,double b=1){x=a;y=b;}  //預設建構函式
    Point(double a){x=1;y=1;} //建構函式
    Point(){} //預設建構函式

};
void Point::print()
{
    cout
<< x << " " << y << endl; }

    所以,可以知道預設建構函式總得來說是可以在物件生成的時候,不需要傳入引數,對應情況就是:

Point point;   
Point *point=new Point;

    非預設建構函式就是必須要傳參。關於預設建構函式有以下知識點:

  • 程式沒有定義任何建構函式,則有預設的建構函式Point(){},裡面的成員的值沒有初始化
  • 定義預設建構函式有兩種方式,如上述程式碼展示的,一是定義一個無參的建構函式,二是定義所有引數都有預設值的建構函式
  • 注意:一個類只能有一個預設建構函式!也就是說上述兩種方式不能同時出現,一般選擇 Point(); 這種形式的預設建構函式

帶預設建構函式的動態陣列

    我們來看一下如果一個類帶預設建構函式,如下程式碼是生成靜態和動態陣列的:

#include<iostream>
#include<math.h>
using namespace std;
class Point
{
    double x, y;
public:
    void print();

};
void Point::print()
{
    cout << x << " " << y << endl;
}
int main() {
    //靜態物件陣列
    Point pp[5
]; for (int i = 0; i<5; i++) pp[i].print(); //動態物件陣列 Point *p = new Point[5]; //這裡面5也可以是變數 for (int i = 0; i<5; i++) p[i].print(); //別忘記delete相應的空間 }

    可以看出來,如果一個類帶預設建構函式的話,那麼生成的時候就不需要傳入引數了,方便了不少。

沒有預設建構函式的動態陣列

    如果一個類沒有預設建構函式呢,這種情況就需要傳入引數了,如下程式碼:

#include<iostream>
#include<math.h>
using namespace std;
class Point
{
    double x, y;
public:
    Point(double a, double b);
    void print();
};
Point::Point(double a, double b)
{
    x = a;
    y = b;
}
void Point::print()
{
    cout << x << " " << y << endl;
}
int main()
{
    Point *p[5];//靜態指標陣列
    for (int i = 0; i < 5; i++) {
        p[i] = new Point(i, i);    //其中你可以用自己的方式來初始化物件,例如從鍵盤接收值等
    }
    for (int i = 0; i < 5; i++) {
        p[i]->print();
    }
    Point **pp = new Point *[5];  //動態指標陣列,5也可以是變數
    for (int i = 0; i < 5; i++) {
        pp[i] = new Point(i, i);
    }
    for (int i = 0; i < 5; i++) {
        pp[i]->print();
    }
    //別忘了delete相應的空間
    return 0;
}

    靜態指標陣列是定義了一些的Point指標,通過new的方式來使每個指標指向物件。動態指標陣列是分配固定大小的連續空間,裡面的每個元素型別是Point *,然後把這連續空間的首地址給pp,pp是指向Point *型別的指標。

注意是 new Point *[5]而不是 new (Point *)[5],後者編譯器會報錯

new多維陣列

int *p=new int[2];
int *p=new int[2][3];  //錯誤
int (*p)[3]=new int[2][3];  //正確
int (*p)[4][5]=new int[2][4][5]; //正確

    為啥第二行就錯誤呢?其實我們可以這樣理解:

  • int (*p)[3]其中p是指標,這是毋庸置疑的,那這個指標指向什麼類的資料呢?我們改一下寫法,程式設計int[3] (*p),是不是就很簡潔明瞭呢?p指向的型別是int[3]。
  • new int[2][3]返回的2個int[3]型別的陣列的首地址,賦值給p。
  • 同理,第四行p指向的型別是int[4][5],new int[3][4][5]返回的是3個int[4][5]型別的陣列的首地址,賦值給p。
  • 針對第一行的情況,如果p的一開始地址為1000,假設int佔用4個位元組,那麼執行p++以後,p的地址為1000+4,第三行的情況,如果p的一開始地址為1000,進行p++以後,p的請值為1000+4*3,以此類推,第四行p++以後p的值為1000+4*4*5。