主頁 >  其他 > C++入門篇(3)之類和物件上

C++入門篇(3)之類和物件上

2021-10-13 08:20:32 其他

文章目錄

  • 前言
  • 面向程序與面向物件
  • 類與物件的引入
  • 何為類
  • 類的定義
  • 訪問限定符說明
  • 封裝
  • 類的實體化
  • 類模型
    • 1.如何計算類物件大小
    • 2.類物件的存盤方式
  • this指標
  • 面試題
    • 1.`this`指標存在哪里?
    • 2.this指標可以為空嗎?

前言

在講解了C++的部分基礎后,我們來到了C++的精華部分,類與物件.在本章節中,博主將會帶領大家了解類的定義和類的使用.


面向程序與面向物件

我們熟悉的C語言是面向程序,關注的是程序,通過分析問題而寫出對應的函式并呼叫來解決問題.

而C++是基于面向物件的,關注的是物件,通過把復雜的事情拆解成物件之間的互動完成.

那他們到底什么區別呢?博主這里不解釋,請繼續玩下面看,大家就自然會明白.

類與物件的引入

在c語言中,我們經常會用到結構體,但是在使用結構體上,C和C++ 卻有一定差異,比如下圖兩張圖:

image-20211011162712446

你會發現,在C++中,如果想定義鏈表的時候,在內部可以直接寫結構體名,而不需要struct,原因:在c語言中,struct是結構體,但是在c++中,struct卻被升級為.


何為類

類,即是一種型別,和int,char等性質一樣,只是類的功能與作用比它們大很多.具體大多少呢?我們往下看.


pp

類的定義

class className
{
	// 類體:由成員函式和成員變陣列成
}; // 一定要注意后面的分號

class為關鍵字,用于定義類.classname為類名,即我們定義的類的名字.

其中,類里面的函式稱為類的方法或者成員函式

類里面的變數稱為類的屬性或者成員變數

其中,這里博主要先介紹下類訪問限定符:public(公有),protected(保護),private(私有),其中public的作用是無論類內還是類外,都可以訪問類的屬性和方法,后兩者的作用是類外不能訪問,類內可以訪問,至于后兩者區別是什么?博主在后面的章節會詳細介紹.

現在,我們來定義一個日期類

class Date
{
    
private:
  	int _year;
    int _month;
    int _day;
    
};

注意:類的方法定義有兩種方式,一是宣告與定義一起,二是宣告與定義分離.

第一種:

class Date
{
public:
void print()
{
  cout<<"我們創建的第一個類"<<endl;
}
};

第二種:

class Date
{
public:
void print();
};

void Date:: print()     //需要使用 類名 加上 類作用域符號::在函式名前面.
{
cout<<"我們創建的第一個類"<<endl;
}

那這兩種定義方式有什么區別呢?

如果所定義的函式比較短,且沒有回圈和遞回,便可以函式宣告與定義放在一起.

如果所定義的函式比較長,且含有回圈或者遞回,那么函式必須宣告與定義分離.

原因是,如果成員函式在類的內部定義,編譯器會把函式當成行內函式進行展開.如果含有遞回或者回圈,可能會被忽略.

現在我們知道了完整的類定義方法,博主便拋出一個需求:

定義一個計算類, 其有屬性n,代表一個數字n.該類具有兩個方法,一是給_n賦值,一是計算1累加到n的值,然后輸出.

class caculate
{
public:
    void outn(int n)    //宣告與定義一起
    {
        _n = n;
    }
    void sumval();     //宣告與定義分離
private:
    int _n;
};

void caculate:: sumval()
{
    int ans = 0;
    for(int i = 1;i<=_n;i++)
    {
        ans+=i;
    }
    cout<<"累加結果為:"<<ans<<endl;
}

訪問限定符說明

  1. public修飾的成員在類外可以直接被訪問(已講解)

  2. protected和private修飾的成員在類外不能直接被訪問(此處protected和private是類似的)(已講解)

  3. 訪問權限作用域從該訪問限定符出現的位置開始直到下一個訪問限定符出現時為止

  4. class的默認訪問權限為private,struct為public(因為struct要兼容C)

其中第四點的意思是,如果我們在定義類時不寫訪問限定符,那么class類中成員是默認為private屬性,而struct類中的成員默認public屬性.

問題:C++中struct和class的區別是什么?
解答:C++需要兼容C語言,所以C++中struct可以當成結構體去使用,另外C++中struct還可以用來定義類,
和class是定義類是一樣的,區別是struct的成員默認訪問方式是public,class是的成員默認訪問方式是
private.


封裝

面向物件有三個特點,分別是:封裝,繼承與多型.

博主在這篇文章主要介紹封裝,那么什么是封裝呢?

封裝:將資料和操作資料的方法進行有機結合,隱藏物件的屬性和實作細節,僅對外公開介面來和物件進行互動

其實簡而言之就是 保證資料的安全性. 比如我們上面介紹類的定義時候其實就是封裝特性,利用訪問限定符,限制性的讓某些資料只在某些地方可以訪問.

而封裝的特性其實就好比去看 兵馬俑,學習c語言時候是沒有封裝特性的,也就相當于兵馬俑沒有圍欄,游客可能會去坑里涂畫,造成兵馬俑不安全,但是C++有了該特性,就相當于給兵馬俑修了圍欄,游客只能按照特定的路線去觀看兵馬俑,而不會破壞兵馬俑.


類的實體化

概念: 用類創建物件的程序稱為類的實體化

其中我們創建的類就好像一張圖紙,而我們通過該圖紙建造出來的房子就是物件,而這個建造的程序就稱為 類的實體化

這個圖紙在我們生活中是不占據空間的,但是建造出來的防止確占據很大空間.

這在我們的程式中同樣如此,我們設計的類并不會占據空間,但是通過類實體化出來的空間確占據空間.

類的實體化例子:

image-20211011193454388

通過我們創建的類—這個可以知道身高體重名字,以及可以說話的抽象類,而在右邊實體出來無數個具有這些功能的物件,就是實體化.


類模型

在看下一知識點前,大家猜猜下面的結果是啥:

class person
{
public:
    void say()
    {
        cout << "我可以說話" << endl;
    }
    double height;
    string name;
    double weight;
};

int main()
{
    person man1;
    man1.height = 122.3;
    man1.name = "dddd";
    man1.weight = 123.4;
    
    person man2;
    man2.height = 150.3;
    man2.name = "uuuu";
    man2.weight = 326.1;
    
    if(sizeof(man1) == sizeof(man2)) cout<<"111111111111111111111111";
    else cout<<"222222222222222222";
    return 0;
}

答案:

image-20211011200816145

其實這樣很好理解,man1和man2都是創建的物件,相當于房子,而他們的圖紙是同一份,也就是說創建出來的防止空間占據一樣大,那無論房子里面裝了多少東西,房子占據的空間仍一樣大.


1.如何計算類物件大小

那么,如何計算類物件的大小呢?其實類的大小計算和在c語言中結構體計算方法一模一樣,并且只計算成員屬性,成員方法不需要計算.

比如:

class person
{
public:
    void say()
    {
        cout << "我可以說話" << endl;
    }
private:
    double height;
    char name[20];
    double weight;
};

按照結構體對齊,我們知道,height占據8位元組,此時偏移量已經到了8,剛好是8的整數倍,所以name從8開始往后又占據20位元組,此時一共占據了28位元組,偏移量也已經是28了,而28并不是8的整數倍,所以需要往后空出4位元組,也就是現在消耗了32位元組,偏移量也達到了32%8==0,所以weight開始往后占據8位元組,到此,一共占據40位元組,而40也是8的倍數,所以person類物件的大小是40位元組

image-20211011203125496

2.類物件的存盤方式

我們知道,一個類一般是包括成員屬性和成員方法的,那么其實體出的物件,會是怎樣存兩者的呢?

答:

每個物件都會存盤其成員屬性,但不會存盤成員方法,而類的成員方法是放在一個公共區域(代碼段)中.

原因:

每個物件都有不同的屬性(屬性值不一樣),但是他們的方法確是一樣的(方法定義上),而不同的物件,我們只需要知道其屬性,然后需要哪個方法就去公共區域呼叫哪個方法,這將會極大的節約空間.反之,如果每個物件都存盤一個相同的方法,就會造成極大的空間浪費


this指標

什么是this指標呢?這個問題先放一放,現在我們會想一下學習資料結構時候,以堆疊為例.

我們給某一個創建的堆疊放資料時候,函式宣告是這樣的

void StackPush(Stack* stack,DataType x);

我們要判斷堆疊是否滿時,函式宣告是這樣的

bool StackFull(Stack* stack);

我們要彈出堆疊的資料時候,函式宣告是這樣的

void stackPop(Stack* stack);

我們會發現,無論如何我么都必須給函式傳一個堆疊指標過去,否則函式的操作物件將不知道.但是在類中,是否存在這種情況呢?

我們看下面:

class caculate
{
public:
    void init(int m,int n)
    {
        _m = m,_n = n;
    }
    void sum()
    {
        int ans = _m + _n;
        cout <<"相加結果為"<<ans<<endl;
    }
    void sub()
    {
		int ans = _m - _n;
        cout <<"相乘結果為"<<ans<<endl;
    }
private:
    int _m;
    int _n;
};

int main()
{
    caculate p1;
    p1.init(1,2);
    p1.sum();
    p1.sub();
    return 0;
}

image-20211011210211986

在上面的例子中,我們可以清晰的看到,我們通過物件呼叫類方法時候,并沒有傳p1地址,而類函式又是放在公共區域的,它是怎么知道要計算哪一個類呢?而這就是我們要講解的this指標

其實,我么在呼叫函式時候,系統便已經悄悄幫我們轉換了:

比如我們呼叫init時候,編譯器會悄悄傳給init一個caculate*指標,即實際傳參為p1.init(&p1,1,3)

而定義init時候,編譯器也悄悄的給init放了caculate*形參,即實際定義為void init(caculate* this,int m,int n)

而那個悄悄放的指標就稱為this指標,而init內部的_m編譯器會變成this->_m,同理還有this->_n


面試題

1.this指標存在哪里?

通過上面的講解我們可以看到,this指標是函式形參,而形參是放在記憶體四區的堆疊區,所以this指標存在堆疊區

2.this指標可以為空嗎?

下面分別呼叫了PrintAShow函式,請問下面的兩個函式是否會崩潰?

class A
{
public:
	void PrintA()
	{
		cout<<_a<<endl;
	}
	void Show()
	{
		cout<<"Show()"<<endl;
	}
private:
	int _a;
};

int main()
{
	A* p = nullptr;
    p->PrintA();
	p->Show();
}

答:

PrintA呼叫時會崩潰,Show呼叫時順利進行

原因:呼叫PrintA時候,它會接收this指標,然后通過this指標訪問其成員_a(之前已經說過成員值本質是this->成員),但是,但是,但是,我們的p是nullptr,那么this也就是nullptr,而空指標是沒有辦法訪問其成員的,所以報錯.

那么this指標可以為空指標嗎? 答案是可以的,但是要注意分情況,正如上面介紹的面試題一樣

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/310575.html

標籤:其他

上一篇:Windows下安裝軟體提示error 2755 怎么處理

下一篇:30天自制作業系統——第二十四天增加命令列視窗

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more