1. 程式人生 > 其它 >C++中的類,結構體,建構函式和解構函式

C++中的類,結構體,建構函式和解構函式

struct 和 class的區別

C++中可以通過使用struct、class定義一個類,本質上他們沒有任何的區別,唯一的區別就是struct的預設成員許可權是public,class預設成員許可權是private

建構函式

建構函式(也叫構造器),在物件建立的時候自動調動,一般用於完成物件的初始化工作

特點:
函式名與類名同名,無返回值(void 也不寫),可以有引數,可以過載,可以有多個建構函式
一旦定義了一個建構函式,就必須使用其中一個自定義的建構函式來初始化

Example

class Person {
    int m_age;
    Person() {}
    Person(int age):m_age(age){}
    void display(){
        cout << this->m_age << endl;
    }
};

Person g_p1;        //Person()
Person g_p2();      //這是一個函式宣告,函式名叫g_p2,返回型別Person,無參
Person g_p3(20);    //Person(int)

int main(){
    Person p1;      //Person()
    Person p2();    //這是一個函式宣告,函式名叫g_p2,返回型別Person,無參
    Person p3(20);  //Person(int)

    Person *p4 = new Person;        //Person()
    Person *p5 = new Person();      //Person()
    Person *p6 = new Person(20);    //Person(int)
    return 0;
}

注意

  1. 通過malloc分配的物件不會呼叫建構函式,並且需要注意的是編譯器並不一定會為每一個類生成空的無參建構函式,是否生成建構函式取決於是否需要做些額外的事情(記憶體操作,函式呼叫),比如:
  2. 成員變數在宣告的同事進行了初始化
  3. 有定義虛擬函式
  4. 虛繼承了其他類
  5. 包含了物件型別的成員,且這個成員有建構函式(編譯器生成或者自定義)
  6. 父類有建構函式(編譯器生成或者自定義)

預設情況下成員變數的初始化

Person g_p1;        //全域性區,成員變數初始化為0

int main(){
    Person p1;      //棧區不會被初始化

    Person *p2 = new Person;        //成員變數不會被初始化
    Person *p3 = new Person();      //成員變數初始化為0
    Person *p4 = new Person[3];     //成員變數不會被初始化
    Person *p5 = new Person[3]();   //3個Person物件的成員變數都初始化為0
    Person *p6 = new Person(){};    //3個Person物件的成員變數都初始化為0

    cout << "g_p1"  << g_p1.getAge() << endl;
    cout << "p1"    << g_p1.getAge() << endl;
    cout << "p2"    << g_p2->getAge() << endl;
    cout << "p3"    << g_p3->getAge() << endl;
    cout << "p4"    << g_p4->getAge() << endl;
    cout << "p5"    << g_p5->getAge() << endl;
    cout << "p6"    << g_p6->getAge() << endl;
    return 0;
}

如果自定義了建構函式,除了全域性區,其他記憶體空間的成員變數預設都不會被初始化,需要開發人員手動初始化

Person() {
  memset(this,0,sizeof(Person));//初始化全部成員變數為0
}

解構函式

解構函式(析構器),在物件銷燬的時候自動呼叫,一般用於完成物件的清理工作

特點:

函式名以~開頭,與類同名,無返回值(void也不寫),無參,不可以過載,有且只有一個解構函式

注意

通過malloc分配的物件呼叫free的時候不會呼叫解構函式
建構函式、解構函式要宣告為public,才能被外界正常使用,解構函式通常用來處理物件內部申請的堆空間,在物件銷燬的時候由物件內部自己回收。

class Car
{
private:
    int m_price;
public:
    Car() {};
    ~Car() {};
};

class Person {
    Car *m_car;
    Person() {
        m_car = new Car();
    }
    ~Person() {
        if(m_car == nullptr) return;
        delete m_car;
        m_car = nullptr;
    }
};