C++_類和對象

来源:https://www.cnblogs.com/whale90830/archive/2019/03/12/10520364.html
-Advertisement-
Play Games

類和對象 OOP第二課 1 類的構成 1.1 從結構到類 1.2 類的構成 2 成員函數的聲明 2.1 普通成員函數形式 2.2 將成員函數以內聯函數的形式進行說明 3 對象的定義和使用 3.1 對象的定義 3.2 對象中成員的訪問 3.3 類成員的訪問屬性 3.4 類中成員的訪問方式 3.5 對象 ...


類和對象

OOP第二課

  • 1 類的構成
    • 1.1 從結構到類
    • 1.2 類的構成
  • 2 成員函數的聲明
    • 2.1 普通成員函數形式
    • 2.2 將成員函數以內聯函數的形式進行說明
  • 3 對象的定義和使用
    • 3.1 對象的定義
    • 3.2 對象中成員的訪問
    • 3.3 類成員的訪問屬性
    • 3.4 類中成員的訪問方式
    • 3.5 對象賦值語句
    • 3.6 類的作用域

類(class)是面向對象程式設計的最基本的概念,是C++最強有力的特征,是進行封裝和數據隱藏的工具,它將一個數據結構與一個操作集緊密地結合起來。類對象是類的實例,用類對象模擬現實世界中的事物比用數據對象更確切。

1. 類的構成

1.1 從結構到類

結構是C的一種自定義的數據類型,它把相關聯的數據元素組成一個單獨的統一體。

例2.1有關日期結構的例子
#include <iostream.h>
struct Date {
    int year;
    int month;
    int day;
};
int main()
{
    Date date1;
    date1.year=2003;
    date1.month=8;
    date1.day=25;
    cout<<date1.year<<"."<<date1.month<<"."
    <<date1.day<<endl;
    return 0;
}

⭐class與struct的比較

  • 類是C++對C中結構的擴展。
  • C語言中的struct是數據成員集合,而C++中的類,則是數據成員成員函數的集合。
  • struct是用戶定義的數據類型,是一種構造數據類型。類和struct一樣,也是一種用戶定義的數據類型,是一種構造數據類型
  • C結構無法對數據進行保護和許可權控制,所以結構中的數據是不安全的。C++中的類將數據和與之相關聯的數據封裝在一起,形成一個整體,具有良好的外部介面可以防止數據未經授權的訪問,提供了模塊間的獨立性。

1.2 類的構成

類的成員分兩部分:一部分對應數據的狀態,稱為數據成員,另一部分為作用於該數據狀態的函數,稱為成員函數

類聲明的一般格式如下:

class 類名 {
public:
    公有數據成員;
    公有成員函數;
protected:
    保護數據成員;
    保護成員函數;
private:
    私有數據成員;
    私有成員函數;
};

3個關鍵字: privateprotectedpublic,稱為訪問許可權關鍵字。每個關鍵字下麵又都可以有數據成員和成員函數。

  • private部分稱為類的私有部分,這一部分的數據成員和成員函數稱為類的私有成員。私有成員只能由本類的成員函數訪問,而類外部的任何訪問都是非法的。
  • public部分稱為類的公有部分,這部分的數據成員和成員函數稱為類的公有成員。公有成員可以由程式中的函數訪問,它對外是完全開放的。
  • protected部分稱為類的保護部分,這部分的數據成員和成員函數稱為類的保護成員。保護成員可以由本類的成員函數訪問,也可以由本類的派生類的成員函數訪問,而類外的任何訪問都是非法的。

註意:

  • (1) 類聲明格式中的3個部分並非一定要全有,但至少要有其中的一個部分。
    • 一般一個類的數據成員應該聲明為私有成員,成員函數聲明為公有成員。
  • (2) 類聲明中的privateprotectedpublic三個關鍵字可以按任意順序出現任意次。但是,如果把所有的私有成員、保護成員和公有成員歸類放在一起,程式將更加清晰。
  • (3) private處於類體中第一部分時, 關鍵字private可以省略
  • (4) 數據成員可以是任何數據類型,但不能用自動(auto)、寄存器(register)或外部(extern)進行聲明。
  • (5) 不能在類聲明中給數據成員賦值。C++規定,只有在類對象定義之後才能給數據成員賦初值

用一個類來描述日期,其形式如下:

class Date {
public:
    void setDate(int y,int m,int d);
    void showDate();
private:
    int m_year;
    int m_month;
    int m_day;
};

2. 成員函數的聲明

成員函數的聲明通常採用以下兩種方式:

2.1 普通成員函數形式

即在類的聲明中只給出成員函數的原型,而成員函數體寫在類的外部。

返回類型 成員函數 (參數列表);

類外定義的一般形式是:

返回類型 類名∷成員函數名(參數表)
{
// 函數體
}

例如, 以下是表示坐標點的類Coord的聲明

class Coord {
public:
    void setCoord (int,int); // 設置坐標點
    int getx(); // 取x坐標點
    int gety(); // 取y坐標點
private:
    int x,y;
};
void Coord∷setCoord(int a,int b){ x=a; y=b;}
int Coord::getx(){ return x;}
int Coord::gety(){ return y;}

內聯函數和外聯函數

類的成員函數可以分為內聯函數和外聯函數。

  • 內聯函數是指那些定義在類體內的成員函數,即該函數的函數體放在類體內。而說明在類體內,定義在類體外的成員函數叫外聯函數。外聯函數的函數體在類的實現部分。
  • 內聯函數在調用時不是像一般函數那樣要轉去執行被調用函數的函數體,執行完成後再轉回調用函數中,執行其後語句,而是在調用函數處用內聯函數體的代碼來替換,這樣將會節省調用開銷,提高運行速度。
  • 內聯函數與帶參數的巨集定義進行一下比較,它們的代碼效率是一樣的,但是內聯函數要優於巨集定義,因為內聯函數遵循函數的類型和作用域規則,它與一般函數更相近,在一些編譯器中,一旦關上內聯擴展,將與一般函數一樣進行調用,調試比較方便。
  • 外聯函數變成內聯函數的方法很簡單,只要在函
    數頭前面加上關鍵字inline就可以了。

2.2 將成員函數以內聯函數的形式進行說明

有兩種格式將成員函數聲明為類的內聯函數:

  • (1)隱式聲明 直接將函數聲明在類內部。
class Coord{
public:
    void setCoord(int a,int b)
    { x=a; y=b;}
    int getx()
    { return x;}
    int gety()
    { retrun y;}
private:
    int x,y;
};
  • (2)顯式聲明

在類聲明中只給出成員函數的原型,而成員函數體寫在類的外部。為了使它起內聯函數的作用,在成員函數返回類型前冠以關鍵字“inline”。

這種成員函數在類外定義的一般形式是:

inline 返回類型 類名::成員函數名(參數表)
{
// 函數體
}

class Coord{
public:
    void setCoord(int,int);
    int getx();
    int gety();
private:
    int x,y;
};
inline void Coord::setCoord(int a,int b)
{ x=a; y=b;}
inline int Coord::getx(){ return x;}
inline int Coord::gety(){ return y; }

說明

  • (1)使用inline說明內聯函數時,必須使函數體和inline說明結合在一起,否則編譯器將它作為普通函數處理。
inline void Coord:: setCoord(int ,int);
// 不能說明這是一個內聯函數
  • (2) 通常只有較短的成員函數才定義為內聯函數,對較長的成員函數最好作為一般函數處理。
class Date{
public:
    void showDate();
private:
    int year;
    int month;
    int day;
};
inline void Date::showDate()
{cout<<year<<'.';<<month<<'.'<<day<<endl;}

3. 對象的定義和使用

類與對象的關係

通常我們把具有共同屬性和行為的事物所構成的集合叫做

在C++中,可以把相同數據結構相同操作集對象看成屬於同一類。

在C++中,類也是一種用戶自定義數據類型,類的對象可以看成是該類類型的一個實例,定義一個對象和定義一個變數相似。類與對象間的關係,可以用數據類型int和整型變數i之間的關係類比。

C++把類的變數叫做類的對象,對象也稱為類的實例。

3.1 對象的定義

對象的定義, 也稱對象的創建

在C++中可以用以下兩種方法定義對象:

(1) 在聲明類的同時,直接定義對象。

class Coord {
public:
    void setCoord(int,int);
    int getx();
    int gety();
private:
    int x,y;
} op1,op2;

(2) 聲明瞭類之後,在使用時再定義對象

class Coord {
    //…
};
// …
main()
{
    Coord op1,op2;
    // …
}

說明:

  • 在聲明類的同時定義的對象是一種全局對象,在它的生存期內任何函數都可以使用它。
  • 聲明瞭一個類便聲明瞭一種類型,它並不接收和存儲具體的值,只作為生成具體對象的一種“樣板”,只有定義了對象後,系統才為對象分配存儲空間。

3.2 對象中成員的訪問

當定義了一個類的對象後,就可以訪問對象的成員了。在類的外部可以通過類的對象對公有成員進行訪問,訪問對象成員要使用操作符“.”。

訪問的一般形式是:

  • 對象名.數據成員名
  • 對象名.成員函數名(參數表)

其中“.”叫做對象選擇符,簡稱點運算符

例2.2 使用類Coord的完整程式
#include<iostream.h>
class Coord {
public:
    void setCoord(int a,int b)
    { x=a; y=b; }
    int getx()
    { return x; }
    int gety()
    { return y; }
private:
    int x,y;
};
void main()
{
    Coord op1,op2;
    int i,j;
    op1.setCoord(5,6); // 調用op1的setCoord(),初始化對象op1
    op2.setCoord(7,8); // 調用op2的setCoord(),初始化對象op2
    i=op1.getx(); // 調用op1的getx(),取op1的x值
    j=op1.gety(); // 調用op1的gety(),取op1的y值
    cout<<"op1 i= "<<i<<" op1 j= "<<j<<endl;
    i=op2.getx(); // 調用op2的getx(),取op2的x值
    j=op2.gety(); // 調用op2的gety(),取op2的y值
    cout<<"op2 i= "<<i<<" op2 j= "<<j<<endl;
}

說明:

  • 對象名.成員名實際上是一種縮寫形式,它表
    達的意義是:對象名.類名::成員名
void main( )
{
    Date date1;
    date1.setDate(2006,9,21);
    //……
}
  • 在類的內部所有成員之間都可以通過成員函數直接訪問,但是類的外部不能訪問對象的私有成員
例2.3 一個存在錯誤的程式
#include <iostream.h>
class Date {
public:
    void setDate(int y,int m,int d);
    void showDate();
private:
    int year;
    int month;
    int day;
};
void Date∷setDate(int y,int m,int d)
{
    year=y;
    month=m;
    day=d;
}
inline void Date∷showDate()
{
    cout<<year<<"."<<month<<"."<<day<<endl;
}
void main()
{
    Date date1,date2;
    cout<<"Date1 set and output:"<<endl;
    date1.setDate(1998,4,28);
    cout<<date1.year<<"."<<date1.month<<"."<<date1.day<<endl; //錯誤
    date1.showDate();
    cout<<"Date2 set and output: "<<endl;
    date2.setDate(2002,11,14);
    cout<<date2.year<<"."<<date2.month<<"."<<date2.day<<endl; //錯誤
    date2.showDate();•
}
  • 在定義對象時,若定義的是指向對象的指針,則訪問此對象的成員時,要用“->”操作符。
void main( )
{
    Date *date3;
    date3->setDate(2001,8,15);
    //……
}

3.3 類成員的訪問屬性

類成員有三種訪問屬性:公有(public)私有(private)保護(protected)

  • 說明為公有的成員不但可以被類中成員函數訪問;
    還可在類的外部,通過類的對象進行訪問。
  • 說明為私有的成員只能被類中成員函數訪問,不能
    在類的外部,通過類的對象進行訪問。
  • 說明為保護的成員除了類本身的成員函數可以訪
    問外,該類的派生類的成員也可以訪問,但不能在類的
    外部,通過類的對象進行訪問。類成員的訪問屬性

類的成員對類對象的可見性和對類的成員函數的可見性是不同的。

類的成員函數可以訪問類的所有成員,而類的對象對類的成員的訪問是受類成員的訪問屬性的制約的。

3.4 類中成員的訪問方式

  • 類中成員互訪:直接使用成員名
  • 類外訪問:使用“對象名.成員名”方式訪問 public 屬性的成員
class Sample{
public:
    int k;
    int geti(){return i;}
    int getj(){return j;}int getk(){return k;}
private:
    int i;
protected:
    int j;
};
//……
Sample a; //定義類Sample的對象a
a.i; //非法,類Sample的對象a不能訪問類的私有成員i
a.j; //非法,類Sample的對象a不能訪問類的保護成員j
a.k; //合法,類Sample的對象a能訪問類的公有成員k
//……

一般來說,公有成員是類的對外介面,而私有成員和保護成員是類的內部數據和內部實現,不希望外界訪問。

將類的成員劃分為不同的訪問級別有兩個好處:一是信息隱蔽,即實現封裝;二是數據保護,即將類的重要信息保護起來,以免其它程式不恰當地修改。

3.5 對象賦值語句

兩個同類型的變數之間可以相互賦值。同類型的對象間也可以進行賦值,當一個對象賦值給另一個對象時,所有的數據成員都會逐位拷貝

例2.5
#include<iostream.h>
class abc{
public:
    void init(int i,int j) { a=i; b=j; }
    void show(){ cout<<a<<" "<<b<<endl; }
private:
    int a,b;
};
main()
{
    abc o1,o2;
    o1.init(12,34);
    o2=o1; // 將對象o1數據成員的值賦給對象o2
    o1.show();
    o2.show();
    return 0;
}

說明:

  • 在使用對象賦值語句進行對象賦值時,兩個對象的類型必須相同,如果對象的類型不同,編譯時將出錯。
  • 兩個對象之間的賦值,僅僅使這些對象中數據成員相同,而兩個對象仍是分離的。
  • 例2.5的對象賦值是通過預設的賦值運算符函數實現的。
  • 當類中存在指針時,使用預設的賦值運算符進行對象賦值,可能會產生錯誤

3.6 類的作用域

所謂類的作用域就是指在類聲明中的一對花括弧所形成的作用域。

  • 一個類的所有成員都在該類的作用域內,一個類的任何成員可以訪問該類的其他成員
  • 一個類的成員函數可以不受限制地訪問類的成員,而在類的外部,對該類的數據成員和成員函數的訪問則要受到一定的限制,有時甚至是不允許的,這體現了類的封裝功能。
例2.6 理解類的作用域
# include<iostream.h>
class myclass{
public:
    int i;
    void init(int);
    void show(){ cout<<“i=” <<i<<endl;} // 可以訪問類中的數據成員i
};
void myclass::init(int si){ i=si;} // 可以訪問類中的數據成員i
int fun(){ return i; } // 非法,不能直接訪問類中的i
void main()
{
    myclass ob;
    ob.init(5); // 給數據成員i賦初值5
    ob.show();
    i=8; // 非法,不能直接訪問類中的i,可改寫成ob.i=8
    ob.show();
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、如何安裝Angular 在文件夾中打開cmd,輸入nmp init創建一個package.json。這個可以一路回車跳過(如果沒有特別要註明)。nmp是前臺的包,用於管理後臺。成功創建package.json後再輸入nmp install bower -g,bower推薦安裝到全局,這裡bowe ...
  • 近來經常用到分散式事務,這裡總結一下,我們目前的使用場景基本都是採用事務消息方式。那麼說到分散式不得不談的CAP CAP理論概述 一個分散式系統最多只能同時滿足一致性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance)這三項中的兩項。 ...
  • 前言 以前總是採用很Low的方式太同一臺伺服器上部署多個Web應用,步驟是這樣的:Copy Tomcat目錄-->更改conf/server.xml三個埠號 >部署war包 >分別啟動訪問。 這樣是最簡單的方式,但事實上是不推薦的,因為如果伺服器資源有限,需要部署的應用數目一旦增加,會給伺服器帶來 ...
  • Spring Cloud是什麼? Spring Cloud是一系列框架的有序集合。它利用Spring Boot的開發便利性巧妙地簡化了分散式系統基礎設施的開發,如服務發現註冊、配置中心、消息匯流排、負載均衡、斷路器、數據監控等,都可以用Spring Boot的開發風格做到一鍵啟動和部署。Spring並 ...
  • 題意 "鏈接" 長度為$n$的序列,用紅黃藍綠染色,其中紅黃只能是偶數,問方案數 Sol 生成函數入門題 任意的是$e^x$,偶數的是$\frac{e^x + e^{ x}}{2}$ 最後化完是$\frac{e^{4x} + 2e^{2x}+1}{4} = \frac{4^n+2 2^{n+1}}{ ...
  • 微信 什麼是微信也不多說,跟前面的支付寶一樣的 微信支付 微信支付也有個沙箱環境,沙箱環境官方文檔 由文檔中那句很顯眼的話所得,即使是測試環境也需要真實的商戶號,所以這個就沒法想支付寶那樣用沙箱賬號來演示了。至於為什麼沒有沙箱賬號這就不得而知了,想接入微信支付商戶的朋友,請移步先註... ...
  • Java Web工程連接MySQL資料庫 一、 準備工作 1.下載連接MySQL資料庫的JDBC (可以去官網下,也可以去百度雲找) 2.將下載的jar文件複製到Tomcat的lib目錄下 3.新建一個Web工程,將下載的jar文件複製過來 ps:第3步是直接複製jar文件,然後在粘貼在WEB IN ...
  • Note of Python Math math 庫是Python 提供的內置數學類函數庫,而其中複數類型常用於科學計算,一般計算並不常用,因此math 庫不支持複數類型。math 庫一共提供4個數學常數和44個函數(包括16個數值表示函數、8個冪對數函數、16個三角對數函數和4個高等特殊函數)。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...