C++入門04 --封裝,內(nèi)存布局,內(nèi)存分配,構(gòu)造/析構(gòu)函數(shù)

封裝

  • 成員變量私有化,提供公共的set,get方法給外界去訪問成員變量;
#include <iostream>
using namespace::std;

struct Person {
    
private:
    int m_age;
    
public:
    void setAge(int age){
        this->m_age = age;
    }
    int getAge(){
        return this->m_age;
    }
    
};

int main(int argc, const char * argv[]) {
    
    Person person;
    person.setAge(20);
    int age = person.getAge();
    
    cout << "person age = " << age << endl;
    
    return 0;
}
  • this是指針,通過(guò)指針訪問結(jié)構(gòu)體的成員,必須用箭頭

內(nèi)存布局

  • 每個(gè)應(yīng)用都有自己的獨(dú)立的內(nèi)存空間,其內(nèi)存空間一般都有以下幾個(gè)區(qū)域:
    • 代碼區(qū):用于存放代碼;
    • 數(shù)據(jù)全局區(qū):用于存放全局變量;
    • 棧區(qū):沒調(diào)用一個(gè)函數(shù)就會(huì)給函數(shù)分配一段連續(xù)的棧空間,等函數(shù)調(diào)用完畢后,系統(tǒng)會(huì)自動(dòng)回收這段??臻g;
    • 堆空間:需要主動(dòng)區(qū)申請(qǐng)和釋放;

堆空間

  • 在程序運(yùn)行過(guò)程中,為了能自由控制內(nèi)存的生命周期,大小,會(huì)經(jīng)常使用堆空間的內(nèi)存;
  • 堆空間的申請(qǐng)與釋放:
    • malloc / free
    • new / delete
    • new [ ] / delete [ ]
  • 注意點(diǎn):
    • 申請(qǐng)堆空間成功后,會(huì)返回那一段堆空間的內(nèi)存地址;
    • 申請(qǐng)與釋放必須是一對(duì)一的關(guān)系,否則會(huì)出現(xiàn)內(nèi)存泄漏;
#include <iostream>
using namespace::std;

void test1() {
    //申請(qǐng)4個(gè)字節(jié)的堆空間內(nèi)存
    int *p = (int *)malloc(4);
    *p = 10;
    
    //釋放堆空間內(nèi)存
    free(p);
}

void test2() {
    //申請(qǐng)4個(gè)字節(jié)的堆空間內(nèi)存
    int *p = new int;
    *p = 20;
 
    //釋放堆空間內(nèi)存
    delete p;
}

void test3(){
    //申請(qǐng)4*10個(gè)字節(jié)的堆空間內(nèi)存
    int *p1 = (int *)malloc(sizeof(int) * 10);
    p1[0] = 10;
    p1[1] = 10;
    p1[2] = 10;
    p1[3] = 10;
    //釋放
    free(p1);
    
    //申請(qǐng)4*10個(gè)字節(jié)的堆空間內(nèi)存
    int *p2 = new int[10];
    
    //釋放
    delete [] p2;
}

int main(int argc, const char * argv[]) {
    
    test1();
    test2();
    test3();
    
    return 0;
}

堆空間的初始化

#include <iostream>
using namespace::std;

void test4() {
    int size = sizeof(int);
    //申請(qǐng)4個(gè)字節(jié)的堆空間內(nèi)存
    int *p = (int *)malloc(size);
    //從p開始的4個(gè)字節(jié)都存放0
    memset(p, 0, size);
    
    cout << *p << endl;
}

void test5(){
    //未初始化
    int *p1 = new int;
    //初始化為0
    int *p2 = new int();
    //初始化為5
    int *p3 = new int(5);
    //數(shù)組元素未被初始化
    int *p4 = new int[3];
    //3個(gè)數(shù)組元素都被初始化為0
    int *p5 = new int[3]();
    //3個(gè)數(shù)組元素都被初始化為0
    int *p6 = new int[3]{};
    //數(shù)組首元素被初始化為5,其他元素被初始化為0
    int *p7 = new int[3]{5};
}

int main(int argc, const char * argv[]) {
    
    test4();
    test5();
    
    return 0;
}
  • memset函數(shù),主要用來(lái)給堆空間內(nèi)存初始化,賦值的;且可以實(shí)現(xiàn)將較大的數(shù)據(jù)結(jié)構(gòu)(結(jié)構(gòu)體,數(shù)組)的內(nèi)存快速清零;

對(duì)象的內(nèi)存

  • C++中對(duì)象的內(nèi)存可以存在于三種內(nèi)存區(qū)域;
  • 棧區(qū):函數(shù)里面的局部變量;
  • 全局區(qū):全局變量;
  • 堆區(qū):動(dòng)態(tài)申請(qǐng)堆內(nèi)存(malloc / new)
#include <iostream>
using namespace::std;

struct Person {
    
private:
    int m_age;
    
public:
    void setAge(int age){
        this->m_age = age;
    }
    int getAge(){
        return this->m_age;
    }
};

//全局區(qū)內(nèi)存
Person g_p1;

int main(int argc, const char * argv[]) {
    
    //棧區(qū)內(nèi)存
    Person person;
    
    //堆區(qū)內(nèi)存
    Person *p = new Person();
    
    return 0;
}

構(gòu)造函數(shù)

  • 構(gòu)造函數(shù)也叫做構(gòu)造器,在對(duì)象創(chuàng)建的時(shí)候自動(dòng)調(diào)用,一般用于完成對(duì)象的初始化操作;
  • 其特點(diǎn)有如下:
    • 函數(shù)名于類名相同,無(wú)返回值,可以有參數(shù),可以重載,可以有多個(gè)構(gòu)造函數(shù);
    • 一旦自定義構(gòu)造函數(shù),必須用其中一個(gè)構(gòu)造函數(shù)來(lái)初始化對(duì)象;
  • 通過(guò)malloc分配的對(duì)象不會(huì)調(diào)用構(gòu)造函數(shù);
  • 在某些特定情況下,編譯器會(huì)為類生成空的無(wú)參的構(gòu)造函數(shù);
#include <iostream>

using namespace::std;

struct Person {
    int m_age;
    
    //構(gòu)造函數(shù)的重載
    Person() {
        cout << "Person()" << endl;
    }
    
    Person(int age) {
        this->m_age = age;
        cout << "Person(int age)" << endl;
    }
    
};

int main(int argc, const char * argv[]) {
    //會(huì)調(diào)用構(gòu)造函數(shù)Person()
    Person person;
    person.m_age = 20;
    
    //會(huì)調(diào)用構(gòu)造函數(shù)Person(int age)
    Person person1 = Person(30);
    
    //會(huì)調(diào)用構(gòu)造函數(shù)Person()
    Person *p1 = new Person();
    //會(huì)調(diào)用構(gòu)造函數(shù)Person(int age)
    Person *p2 = new Person(33);
    
    //不會(huì)調(diào)用構(gòu)造函數(shù)
    Person *p3 = (Person *)malloc(sizeof(Person));
    
    return 0;
}
構(gòu)造函數(shù)的調(diào)用
#include <iostream>

using namespace::std;

struct Person {
    int m_age;
    
    //構(gòu)造函數(shù)的重載
    Person() {
        //所有成員變量,全部清零
        memset(this, 0, sizeof(Person));
        cout << "Person()" << endl;
    }
    
    Person(int age) {
        this->m_age = age;
        cout << "Person(int age)" << endl;
    }
    
};

//全局區(qū)
Person g_person1;
//這是個(gè)函數(shù)聲明,不是調(diào)用Person的構(gòu)造函數(shù)
Person g_person2();
Person g_person3(30);

int main(int argc, const char * argv[]) {
    
    //棧區(qū)
    Person person1;
    //這是個(gè)函數(shù)聲明,不是調(diào)用Person的構(gòu)造函數(shù)
    Person person2();
    Person person3(31);
    
    //堆區(qū)
    Person *p1 = new Person;
    Person *p2 = new Person();
    Person *p3 = new Person(32);
    
    return 0;
}
  • 全局區(qū),調(diào)用兩次構(gòu)造函數(shù);
  • 棧區(qū),調(diào)用兩次構(gòu)造函數(shù);
  • 堆區(qū),調(diào)用三次構(gòu)造函數(shù);

析構(gòu)函數(shù)

  • 析構(gòu)函數(shù)也叫析構(gòu)器,在對(duì)象銷毀的時(shí)候自動(dòng)調(diào)用,一般用于完成對(duì)象的清理工作;
  • 析構(gòu)函數(shù)的特點(diǎn):
    • 函數(shù)名以~開頭,與類同名,無(wú)返回值,無(wú)參數(shù),不可以重載,有且只有一個(gè)析構(gòu)函數(shù);
    • 通過(guò)malloc分配的對(duì)象的在free的時(shí)候是不會(huì)調(diào)用析構(gòu)函數(shù)的;
    • 構(gòu)造函數(shù)與析構(gòu)函數(shù)都要被聲明為public,這樣才能被外界正常使用;
#include <iostream>

using namespace::std;

struct Person {
    
    int m_age;
    
    //構(gòu)造函數(shù)
    Person() {
        cout << "Person()" << endl;
    }
    
    //析構(gòu)函數(shù) 回收Person對(duì)象內(nèi)部申請(qǐng)的堆空間car
    ~Person() {
        cout << "~Person()" << endl;
    }
    
};

int main(int argc, const char * argv[]) {
    //棧區(qū)person對(duì)象
    Person person;
    
    //堆區(qū)person對(duì)象
    Person *p = new Person();
    delete p;
    
    return 0;
}
  • 會(huì)調(diào)用兩次構(gòu)造函數(shù),析構(gòu)函數(shù);

對(duì)象的內(nèi)存管理

#include <iostream>

using namespace::std;


struct Car {
    
    int m_price;
    
    Car() {
        cout << "Car()" << endl;
    }
    
    ~Car() {
        cout << "~Car()" << endl;
    }
};

struct Person {
    
    int m_age;
    Car *car;
    
    //構(gòu)造函數(shù)
    Person() {
        cout << "Person()" << endl;
        car = new Car();
    }
    
    //析構(gòu)函數(shù) 回收Person對(duì)象內(nèi)部申請(qǐng)的堆空間car
    ~Person() {
        cout << "~Person()" << endl;
        delete this->car;
    }
    
};

int main(int argc, const char * argv[]) {
    
    //堆區(qū)person對(duì)象
    Person *p = new Person();
    
    delete p;
    
    return 0;
}
  • 堆區(qū)person對(duì)象在銷毀之前,必須要銷毀清理內(nèi)部堆區(qū)對(duì)象car,否則會(huì)產(chǎn)生內(nèi)存泄漏;

聲明與實(shí)現(xiàn)的分離

  • 類的聲明放在.hpp頭文件,類的實(shí)現(xiàn)放在.cpp實(shí)現(xiàn)文件
//  Person.hpp
//  C++11_聲明與實(shí)現(xiàn)的分離
//
//  Created by ljj on 8/12/21.
//

#ifndef Person_hpp
#define Person_hpp

#include <stdio.h>

//聲明
class Person {
    int m_age;
    
public:
    Person();
    ~Person();
    
    void setAge(int age);
    int getAge();
};


#endif /* Person_hpp */
//  Person.cpp
//  C++11_聲明與實(shí)現(xiàn)的分離
//
//  Created by ljj on 8/12/21.
//

#include "Person.hpp"
#include <iostream>

using namespace::std;

//實(shí)現(xiàn)
// :: 域運(yùn)算符
Person::Person(){
    cout << "Person()" << endl;
}

Person::~Person(){
    cout << "~Person()" << endl;
}

void Person::setAge(int age){
    this->m_age = age;
}

int Person::getAge(){
    return this->m_age;
}
  • 最后在main文件中導(dǎo)入#include "Person.hpp"
//  main.cpp
//  C++11_聲明與實(shí)現(xiàn)的分離
//
//  Created by ljj on 8/12/21.
//

#include <iostream>
#include "Person.hpp"

using namespace::std;

int main(int argc, const char * argv[]) {
    
    {
        Person person;
        person.setAge(30);
        cout << person.getAge() << endl;
    }
    
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容