從C++開始的編程生活(4)——類的定義、訪問限定符、類域、類的實例化和this指針

前言

本系列文章承接C語言的學習,需要有C語言的基礎才能學會哦~
第3篇主要講的是有關于C++的類的定義訪問限定符類域類的實例化this指針
C++才起步,都很簡單呢!

目錄

前言

基本語法

訪問限定符

基本語法

類域

類的實例化?

內存對齊規則

this指針

封裝(初步了解)


class為類的關鍵字,后跟類名,{ }中為類的主體。主體中內容稱為類的成員類中的變量稱為類的屬性或者成員變量類中的函數稱為方法或者成員函數

基本語法

為了區分方法的形參和類中的成員變量,通常會在變量前后加一個下劃線,具體怎么標識,看公司或者團隊要求。

//類與對象
class Stack
{//方法void Init(int capacity = 4){_array = (int*)malloc(sizeof(int) * capacity);if (nullptr == _array){perror("malloc申請空間失敗!\n");return;}_capacity = capacity;_top = 0;}void Push(int x){//擴容步驟(省略)_array[_top++] = x;}//·······(省略棧的各種函數)//成員變量int* _array;size_t _capacity;size_t _top;
};
//類名就是類型

類中的成員函數,默認為inline函數

訪問限定符

public公有,在類外可以直接被訪問。設計時成員函數一般是公有的。
private私有,在類外不能直接被訪問。設計時成員變量一般是私有的。
protect保護,在類外不能直接被訪問。在繼承上,和private有區別(在繼承詳細說明)。

基本語法

class Stack
{
//公有
public:void Init(int capacity = 4){_array = (int*)malloc(sizeof(int) * capacity);if (nullptr == _array){perror("malloc申請空間失敗!\n");return;}_capacity = capacity;_top = 0;}
//私有
private:int* _array;size_t _capacity;size_t _top;
};

如上,跟在不同的訪問限定符后,受不同的訪問限定。

?
C++兼容C語言的struct,同時又升級了struct。
C++中,struct和類的唯一區別在于:struct的成員變量和方法默認為publicclass默認為private為求嚴謹,最好自己指明訪問限定符

//不加訪問限定符,默認為public
struct Person
{void Init(const char name[5]){strcpy(_name,name);}void Print(){cout << "姓名:" << _name << endl;}char _name[5];
};int main()
{//可在外部直接使用Person p1;p1.Init("張三");p1.Print();return 0;
}

類域

由類定義的一個新的作用域,類的所有成員都在類域中。類域使得不同的類可以有同名的成員。和命名空間類似,它影響的是編譯器的查找順序規則(具體去看我博客內的C++第一篇喔~)。

成員函數可以進行聲明和定義的分離。
一般我們將聲明放在類中,定義放在另一個文件中。并且為了標識該方法所屬的類,需要用到域作用限定符? ::?

void Stack::Init(int capacity)//注意定義處不要寫缺省參數,缺省參數寫在聲明
{//函數實現省略···
}

類的實例化?

類中的成員變量在沒有實例化時,均不開辟空間,只是一個聲明。我們要將類實例化成對象后,它才能夠存儲數據,我們才能對具體的對象進行操作

class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{Date d1;//實例化出對象d1Date d2;//實例化出對象d2d1.Init(2025, 7, 20);d2.Init(2025, 7, 25);d1.Print();d2.Print();cout << sizeof(d1) << endl;//輸出12,成員變量共12個字節cout << sizeof(d2) << endl;//輸出12,成員變量共12個字節return 0;
}

實例化后,對象只存儲成員變量,不存儲方法指針。因為同一類的對象使用的是相同的方法,所以將方法存儲在公共代碼區即可,不存儲在實例對象里。否則,會重復存儲,浪費空間。

內存對齊規則

成員變量存儲,遵循C語言的內存對齊規則。

第一個成員變量在類起始地址偏移量為0處。
②其他成員變量要對齊到對齊數的整數倍地址處
對齊數 = 編譯器默認對齊數 與 該成員大小 的較小值
④VS編譯器默認的對齊數是8
⑤類的總大小為默認對齊數的整數倍
⑥類中沒有成員時(如仿函數類),總大小為1byte。即使沒有也要開辟空間占位,以表示存在實例對象。

內存對齊的目的方便讀取,讀取數據時可以從在數據類型大小的整數倍位置讀取,不用一字節一字節讀,而是跳躍讀取找到位置后可以一次性讀取,不用再一個字節一個字節拼起來。

this指針

用于指明類方法中區分訪問的成員方法。類方法存儲在公共代碼區,在類方法的角度來看,調用它時,該方法并不清楚是哪個對象調用的它。這就要用到this指針。

類方法中實際上還會隱含一個參數,

void Init(int year, int month, int day)
{//略···
}//在形參列表首位,存在一個省略的參數this指針
void Init(Date* const this, int year, int month, int day)
{//略···
}

我們可以看到有const修飾,該隱藏參數是不可以修改的
調用時,會傳入調用方法的對象的地址作為this指針

d1.Init(2025, 7, 21);
//d1.Init(&d1, 2025, 7,21);
//實際上是這樣傳參的,但是不能這樣寫

?C++編譯器會自動添加的隱含的this,程序員不可以自行添加,會報錯。但是可以在函數體內添加使用

void Print()
{cout << _year << "/" << _month << "/" << _day << endl;
}
//等價于
void Print()
{cout << this->_year << "/" << this->_month << "/" << this->_day << endl;
}

通過this指針,對象調用類方法時,才可以在類方法內訪問對象的屬性。

類指針的易錯點:

class A
{
public:void Print(){cout << "Hi!" << endl;}
private:int _a;
};class B
{
public:void Print(){cout << "Hi!" << endl;cout << _b << endl;}
private:int _b;
};int main()
{//正常運行,輸出“Hi!”A* pa = nullptr;pa->Print();//運行崩潰B* pb = nullptr;pb->Print();return;
}

如上,papb都是空指針
pa指針調用Print方法能正常運行,是因為運行時未對這個空指針進行解引用操作
pb指針調用Print方法會運行崩潰,是因為運行到語句 cout << _b << endl 時,_b前有隱藏的this指針,所以這里實際上有一個 this->_b ,這里的this即是傳入的pb空指針,發生解引用錯誤
(“ 指針-> ”為解引用操作喔~)

ps:this指針的創建在棧區

封裝(初步了解)

目的:C++將數據和函數放在類中,隱藏細節和復雜部分,只需要確保代碼能實現目的即可。靠訪問限定符,約束和管理程序員訪問數據,避免細節上的錯誤

關于封裝更多的知識,在之后還有更多可以學習的,敬請關注!!

?~~本文完結!!感謝觀看!!歡迎來我博客做客~~?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/915486.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/915486.shtml
英文地址,請注明出處:http://en.pswp.cn/news/915486.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AD域控制器虛擬化的安全加固最佳實踐

以下是AD域控制器虛擬化安全加固的7項核心實踐&#xff0c;結合最新Windows Server 2022特性與虛擬化環境需求&#xff1a;基礎架構強化? 采用靜態IP分配并確保所有域控節點DNS指向主DC&#xff08;如192.168.1.10&#xff09;? 虛擬機模板需預配置林/域功能級別為Windows Se…

java解析nc氣象數據

1.1pom.xml<dependency><groupId>edu.ucar</groupId><artifactId>netcdfAll</artifactId><version>5.4.1</version></dependency>1.2 netcdf使用/** param type 0 ,1, 2 wind 1 or 2 其他 0 .* return Map* */public Map i…

STC8H8K64U SKDIP28芯片頻率占空比PWM波形

/****PWM輸出任意周期占空比波形*******/ #include "STC8H.h" // #include "intrins.h" // #define uchar unsigned char // #define uint unsig…

【RK3576】【Android14】USB開發調試

獲取更多相關的【RK3576】【Android14】驅動開發&#xff0c;可收藏系列博文&#xff0c;持續更新中&#xff1a; 【RK3576】Android 14 驅動開發實戰指南 硬件接口 RK3576支持兩個USB3.0控制器 驅動開發 dts配置 在“Android14/kernel-6.1/arch/arm64/boot/dts/rockchip/rk…

20. TaskExecutor與ResourceManager心跳

20. TaskExecutor與ResourceManager心跳 現在&#xff0c;需要回過頭看 ResourceManager是如何產生心跳管理服務的。cluster.initializeServices 方法的 heartbeatServices createHeartbeatServices(configuration);產生一個 HeartbeatServicesImpljobmanager的 resourceManag…

OS19.【Linux】進程狀態(上)

目錄 1.情景引入 2.操作系統學科對進程狀態的分類 運行狀態 基于時間片的輪轉調度算法 阻塞狀態 等待IO設備的例子 等待其他進程中需要獲取的數據 進程喚醒 掛起狀態(全稱為阻塞掛起狀態) 簡單談談虛擬內存管理 就緒狀態 筆面試題 3.Linux對進程狀態的分類 R和S狀…

如何優雅地修改項目的 Android 版本(API 級別)

引言 在 Android 開發的日常迭代中&#xff0c;我們經常需要升級或降級項目的 minSdkVersion、targetSdkVersion 與 compileSdkVersion。升級可以解鎖新特性和性能優化&#xff1b;降級則可能為了兼容舊機型或快速驗證問題。本文將手把手演示在 Android Studio 里修改 Android …

GNU Radio多類信號多種參數數據集生成技巧

參考我的這篇博客&#xff0c;我想自制一個多信號數據集&#xff1a; 【多雷達信號硬件模擬】 3臺USRP1臺VSG信號發生器模擬多雷達信號&#xff0c;1臺USRP產生高斯噪聲模擬更多信道環境&#xff0c;1臺USRP采集信號 需要在多個波段對四種信號進行參數設置&#xff0c;帶寬有…

Ansible + Shell 服務器巡檢腳本

腳本概述這是一個用于服務器日常巡檢的 Shell 腳本&#xff0c;主要功能包括&#xff1a;檢查多臺主機的網絡連通性 監控CPU、內存和磁盤使用率 生成詳細的巡檢報告 通過企業微信發送告警通知核心技術點1. 主機批量管理使用Ansible工具遠程執行命令和腳本 通過主機…

Linux-rpm和yum

一、RPMRPM&#xff08;Red Hat Package Manager&#xff09;是一個用于管理 Red Hat 系列 Linux 發行版&#xff08;如 RHEL、CentOS、Fedora&#xff09;軟件包的工具。RPM 允許用戶以統一的格式來安裝、卸載、升級和查詢軟件包。它是 .rpm 文件的主要工具&#xff0c;后綴名…

手推OpenGL相機的正交投影矩陣和透視投影矩陣(附源碼)

概述計算OpenGL的正交投影矩陣和透視投影矩陣是有現成函數的。自己手推不是為了重復造輪子。手推一遍&#xff0c;可以極大的加強對這兩個矩陣的理解。同時也可以滿足一下自己求知欲。正交投影矩陣手推正交投影矩陣源碼 WGMatrix4x4 WGMatrix4x4::BuildOrtho(double l, double …

【跨國數倉遷移最佳實踐2】MaxCompute SQL執行引擎對復雜類型處理全面重構,保障客戶從BigQuery平滑遷移

本系列文章將圍繞東南亞頭部科技集團的真實遷移歷程展開&#xff0c;逐步拆解 BigQuery 遷移至 MaxCompute 過程中的關鍵挑戰與技術創新。本篇為第二篇&#xff0c;跨國數倉遷移背后 MaxCompute 的統一存儲格式創新。 注&#xff1a;客戶背景為東南亞頭部科技集團&#xff0c;…

react(基礎篇)

React由Meta公司研發&#xff0c;用于構建Web和原生交互界面的庫。 React 官方中文文檔 查看JSX &#xff08;一&#xff09;React組件 用戶界面的一部分&#xff0c;通俗的來講&#xff0c;最小的元素組成的單元&#xff0c;可以實現部分邏輯與功能 房子的門就可以看成一個…

數據結構-哈希表(一)哈希函數、哈希表介紹、優缺點

哈希表 哈希函數哈希表使用了哈希函數來完成key到地址的快速映射&#xff0c;所以在了解哈希表之前&#xff0c;需要先明白哈希函數的概念和特點。 哈希函數的定義 哈希函數 哈希函數是一種將任意長度輸入的數據&#xff0c;轉換成固定長度輸出的算法哈希函數H可以表示為yH(x) …

Shader開發(一)什么是渲染

前言在現代游戲開發和計算機圖形學領域&#xff0c;渲染技術是連接虛擬世界與視覺呈現的關鍵橋梁。無論你是剛接觸圖形編程的新手&#xff0c;還是希望深入理解渲染原理的開發者&#xff0c;掌握渲染的核心概念都是必不可少的第一步。什么是渲染&#xff1f;渲染&#xff08;Re…

策略模式+工廠模式(案例實踐易懂版)

最近,可以說這2025年度,自己更文的次數都大大減少,主要最近大環境不景氣,自己職業也受到波及,學習的東西也是因為AI而變得更多, 沒辦法,你不學,總有人會學,關于AI的我也準備出個專輯,相信絕對幫助到大家 額,好像說多了,言歸正傳,我們看一下今天的主題:策略模式工廠模式 本文主要…

【NLP輿情分析】基于python微博輿情分析可視化系統(flask+pandas+echarts) 視頻教程 - snowNLP庫實現中文情感分析

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;最近寫了一套【NLP輿情分析】基于python微博輿情分析可視化系統(flaskpandasecharts)視頻教程&#xff0c;持續更新中&#xff0c;計劃月底更新完&#xff0c;感謝支持。今天講解snowNLP庫實現中文情感分析 視頻在線地址&…

大根堆,小根堆,雙指針

碼蹄集OJ-大約 #include<bits/stdc.h> using namespace std; priority_queue<int>max2,maxDel; priority_queue<int,vector<int>,std::greater<int>>min2,minDel; const int N1e51; int n,result0,a[N]; int main( ) {cin>>n;for(int i1…

RS485和Modbus

UART協議中&#xff0c;空閑狀態為高電平&#xff0c;也就是1,R25和R27&#xff0c;485收發器特性MAX485 (美信)SSP485 (國產替代)AZRS3080 (安格)供電電壓5V5V3.3V ~ 5.5V靜態電流300μA (接收模式)120μA (接收模式)150μA (接收模式)傳輸速率2.5Mbps10Mbps20Mbps總線負載能力…

【Android】交叉編譯faiss庫 | 問題解決

目錄 一 解決 FAISS 交叉編譯到 Android 時的 BLAS/MKL 依賴問題 二 交叉編譯faiss ■禁用 BLAS并交叉編譯faiss ■使用 OpenBLAS 的 Android 移植版本并交叉編譯faiss 三 報錯處理 ■報錯 ■SWIG 一 解決 FAISS 交叉編譯到 Android 時的 BLAS/MKL 依賴問題