C++——從結構體到類與對象

C++ 類與對象詳解:從結構體到面向對象編程

C++ 的面向對象編程(OOP)核心是?類(Class)?和?對象(Object)。類是用戶自定義的數據類型,用于封裝數據(屬性)和操作數據的方法(行為);對象則是類的實例。本文將從?C 風格結構體?引入,逐步深入講解 C++ 的類和對象,結合代碼和詳細說明。


1. 從 C 風格結構體到 C++ 類

1.1 C 風格結構體(Struct)

在 C 語言中,結構體(struct)用于將多個相關變量組合成一個復合類型:

#include <iostream>
#include <cstring> // 用于 strcpy// C 風格結構體:表示一個學生
struct StudentC {char name[50]; // 姓名(字符數組)int age;       // 年齡float score;   // 分數
};int main() {// 創建結構體變量并初始化StudentC s1;strcpy(s1.name, "Alice"); // C 風格字符串賦值s1.age = 20;s1.score = 95.5f;// 訪問結構體成員std::cout << "Name: " << s1.name << ", Age: " << s1.age << ", Score: " << s1.score << std::endl;return 0;
}

說明

  • 數據完全公開,無法控制訪問權限

  • 操作數據的行為(函數)與數據本身分離(結構體僅包含數據,操作需額外函數實現)

  • 缺乏數據保護機制,容易導致非法修改


1.2 C++ 結構體(增強版)

C++ 保留了?struct,但允許在結構體內定義函數(方法),并支持訪問控制(public/private):

#include <iostream>
#include <string> // 使用 std::string 替代字符數組// C++ 結構體(帶方法)
struct StudentCpp {std::string name; // 更安全的字符串int age;float score;// 結構體內定義方法:打印學生信息void printInfo() {std::cout << "Name: " << name << ", Age: " << age << ", Score: " << score << std::endl;}
};int main() {StudentCpp s2;s2.name = "Bob"; // 直接賦值s2.age = 21;s2.score = 88.0f;s2.printInfo(); // 調用結構體方法return 0;
}

說明

  • C++ 的?struct?默認成員是?public?的(與?class?默認?private?不同)。
  • 可以在結構體內定義方法,但通常更推薦用?class?表達面向對象概念。

1.3 從結構體到類的關鍵轉變

C++ 中?class?和?struct?的唯一區別是默認訪問權限不同:

類是結構體的升級版,通過?訪問修飾符?控制成員的可見性,并強制將數據和方法綁定在一起:

// 使用 class 關鍵字
class Point {int x;  // 默認 privateint y;  // 默認 privatepublic:void print() {cout << "(" << x << ", " << y << ")" << endl;}void set(int newX, int newY) {if (newX >= 0 && newY >= 0) {  // 添加驗證邏輯x = newX;y = newY;}}int getX() const { return x; }  // const 成員函數int getY() const { return y; }
};int main() {Point p1;p1.set(3, 4);// p1.x = 5;  // 錯誤:x 是 private 成員cout << p1.getX() << endl;  // 正確:通過公共接口訪問return 0;
}

關鍵概念

  1. 封裝:將數據和行為組合在一起,并控制訪問權限

  2. 訪問修飾符

    • public:公開的,任何代碼都可以訪問

    • private:私有的,只有類內部可以訪問

    • protected:受保護的,類內部和派生類可以訪問

  3. const 成員函數:承諾不修改對象狀態的成員函數


2. 類的核心特性詳解

2.1?構造函數與初始化

基本構造函數
  • 構造函數
    • 特殊方法,在創建對象時自動調用,用于初始化數據。
    • 語法:ClassName(參數列表) : 初始化列表 {}
class Student {string name;int age;double score;public:// 構造函數Student(const string& n, int a, double s) {name = n;age = a;score = s;}void display() const {cout << name << ", " << age << "歲, 成績: " << score << endl;}
};int main() {Student stu("張三", 18, 90.5);  // 調用構造函數stu.display();return 0;
}

初始化列表(更高效的初始化方式)

class Student {string name;int age;double score;public:// 使用初始化列表的構造函數Student(const string& n, int a, double s) : name(n), age(a), score(s) {  // 初始化列表// 構造函數體}
};

    初始化列表的優勢

    1. 對于類類型成員,直接調用拷貝構造函數而非先默認構造再賦值

    2. 對于 const 成員和引用成員,必須在初始化列表中初始化

    3. 執行效率更高

    默認構造函數
    class Student {// ... 其他成員同上public:Student() : name("無名"), age(0), score(0) {}  // 默認構造函數// 也可以使用默認參數實現Student(const string& n = "無名", int a = 0, double s = 0) : name(n), age(a), score(s) {}
    };int main() {Student stu1;          // 調用默認構造函數Student stu2("李四");  // 使用默認參數return 0;
    }

    2.2 靜態成員(類共享數據)

    靜態成員屬于類本身,而非單個對象,所有對象共享同一份數據:

    #include <iostream>class Student {
    private:static int studentCount; // 靜態成員:記錄學生總數std::string name;public:Student(const std::string& n) : name(n) {studentCount++; // 創建對象時增加計數}static int getStudentCount() { // 靜態方法:訪問靜態成員return studentCount;}
    };// 初始化靜態成員(必須在類外定義)
    int Student::studentCount = 0;int main() {Student s6("Eve");Student s7("Frank");std::cout << "Total Students: " << Student::getStudentCount() << std::endl; // 輸出 2return 0;
    }

    說明

    • 靜態成員需在類外單獨定義和初始化。
    • 靜態方法只能訪問靜態成員,不能訪問非靜態成員。

    3. 對象:類的實例

    3.1 對象的創建與銷毀

    對象是類的實例,通過構造函數初始化,析構函數清理資源:

    #include <iostream>class Resource {
    public:Resource() {std::cout << "Resource acquired!" << std::endl;}~Resource() { // 析構函數std::cout << "Resource released!" << std::endl;}
    };int main() {{Resource res; // 創建對象,調用構造函數// ... 使用 res ...} // 離開作用域,自動調用析構函數return 0;
    }

    輸出

    Resource acquired!
    Resource released!

    析構函數特點

    1. 名稱是?~?加類名,無參數無返回值

    2. 在對象生命周期結束時自動調用

    3. 用于釋放資源、清理內存等收尾工作

    4. 如果不顯式定義,編譯器會生成默認析構函數

    3.2 對象作為函數參數

    對象可以通過值傳遞、引用傳遞或指針傳遞:

    #include <iostream>class Point {
    public:int x, y;Point(int xVal, int yVal) : x(xVal), y(yVal) {}
    };// 1. 值傳遞(拷貝對象)
    void printPointByValue(Point p) {std::cout << "Value: (" << p.x << ", " << p.y << ")" << std::endl;
    }// 2. 引用傳遞(避免拷貝)
    void printPointByRef(const Point& p) {std::cout << "Ref: (" << p.x << ", " << p.y << ")" << std::endl;
    }int main() {Point p1(10, 20);printPointByValue(p1); // 拷貝 p1printPointByRef(p1);   // 直接引用 p1return 0;
    }

    建議

    • 大型對象使用?const?引用傳遞(避免拷貝開銷)。
    • 需要修改對象時使用非?const?引用或指針。

    4. 總結

    概念說明
    結構體(Struct)C 風格數據組合,C++ 增強后支持方法,默認成員公開。
    類(Class)封裝數據和方法,通過訪問修飾符控制可見性,支持構造函數/析構函數。
    對象類的實例,通過構造函數初始化,析構函數清理資源。
    靜態成員屬于類而非對象,所有對象共享同一份數據。
    封裝性通過私有數據和公有方法保護數據安全性。

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

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

    相關文章

    專題:2025數據資產AI價值化:安全、戰略與應用報告|附400+份報告PDF、原數據表匯總下載

    原文鏈接&#xff1a;https://tecdat.cn/?p42885 在數字經濟加速滲透的今天&#xff0c;數據作為核心生產要素的價值愈發凸顯。上市公司作為經濟高質量發展的微觀主體&#xff0c;其數據價值化進程不僅關乎企業自身競爭力&#xff0c;更折射出中國產業數字化轉型的深度與廣度。…

    泛微虛擬視圖-數據虛擬化集成

    文章目錄一、核心概念對比二、功能特性對比1. 數據操作能力2. 業務邏輯支持3. 性能表現三、技術實現差異1. 虛擬表單實現原理2. 視圖實現原理四、典型應用場景對比1. 虛擬表單適用場景2. 視圖適用場景五、配置與管理對比六、性能優化差異虛擬表單優化策略視圖優化策略七、企業級…

    Ubuntu 下 MySql 使用

    1.開發背景開發項目需要使用到數據庫&#xff0c;相對于輕量級的 SQLite&#xff0c;MySql 相對復雜一下&#xff0c;但是可以遠程訪問&#xff0c;還是比較舒服的。2.開發需求Ubuntu 安裝 MySql 服務端&#xff0c;Window 客戶端訪問 Ubuntu 數據庫。3.開發環境Ubuntu20.04 W…

    QT開發技術 【qt應用限制只能啟動一個】

    限制 Qt 程序只能啟動一個實例 在開發 Qt 應用程序時,可能需要限制程序只能運行一個實例,以避免重復啟動。以下是實現這一功能的幾種常用方法。 使用 QSharedMemory 限制單實例 通過共享內存判斷是否已有程序運行,如果存在則退出當前實例。 #include <QApplication&g…

    Android 禁用beam傳輸

    1、打開/packages/apps/Nfc/src/com/android/nfc/beam/BeamManager.java找到startBeamReceive、startBeamSend方法public boolean startBeamReceive(Context context,HandoverDataParser.BluetoothHandoverData handoverData) {synchronized (mLock) {if (mBeamInProgress) {re…

    基于 ETL 工具實現人大金倉數據庫的數據遷移與整合實操指南

    在企業數字化轉型的浪潮下&#xff0c;數據已經成為企業發展的核心資產。人大金倉數據庫憑借其穩定可靠的性能&#xff0c;在國內眾多企業中得到了廣泛應用。但隨著業務的不斷拓展和系統的更新迭代&#xff0c;數據遷移與整合的需求也日益凸顯。無論是將人大金倉數據庫的數據遷…

    TCP 事務全面研究:從原理到優化與故障排除

    一、引言 TCP&#xff08;傳輸控制協議&#xff09;作為互聯網的核心協議之一&#xff0c;已經在全球范圍內運行了近 50 年。自 1974 年由文頓?瑟夫和羅伯特?卡恩設計以來&#xff0c;TCP 經歷了多次修訂和優化&#xff0c;以適應不斷變化的網絡環境和應用需求。TCP 事務是指…

    java實戰-Milvus 2.5.x版本向量庫-通過集合字段變更示例學習相關api demo

    文章目錄前言java實戰-Milvus 2.5.x版本向量庫-通過集合字段變更示例學習相關api demo1. Milvus版本2. 示例邏輯分析3. 集合字段變更示例demo4. 測試前言 如果您覺得有用的話&#xff0c;記得給博主點個贊&#xff0c;評論&#xff0c;收藏一鍵三連啊&#xff0c;寫作不易啊^ _…

    HashMap的get與put流程源碼深度解析

    目錄 一、HashMap基礎結構 二、put操作流程分析 put操作關鍵步驟總結 三、get操作流程分析 get操作關鍵步驟總結 四、延伸 1.hash()方法 2. 擴容 resize()方法的主要邏輯&#xff1a; Java 8中對擴容的優化&#xff1a; 3. 轉向紅黑樹的條件 HashMap作為Java集合框架…

    初識Neo4j之圖數據庫(二)

    目錄 一、圖數據庫如何工作 二、為什么使用圖數據庫 Neo4j 圖數據庫以節點、關系和屬性的形式存儲數據&#xff0c;而不是用表或文檔進行數據存儲。這意味著用戶可以像在白板上畫草圖那樣來組織數據。而且&#xff0c;由于圖數據庫不受限于預先定義的數據模型&#xff0c;因此…

    Python 中 ffmpeg-python 庫的詳細使用

    文章目錄 一、ffmpeg-python庫概述1.1 ffmpeg-python庫介紹1.2 安裝1.3 優勢1.4 常用場景二、基本使用2.1 視頻信息獲取2.2 視頻轉碼三、視頻處理3.1 視頻裁剪3.2 視頻縮放3.3 視頻旋轉四、音頻處理4.1 提取音頻4.2 音頻混合五、高級使用5.1 添加水印5.2 視頻濾鏡5.3 視頻合成5…

    JAVA策略模式demo【設計模式系列】

    策略模式用在統一的入口&#xff0c;但需要根據某個類型判斷后續執行邏輯&#xff0c;例如我最近遇到的場景&#xff1a;我需要對接一個設備&#xff0c;前端請求我這邊&#xff0c;我再去和設備交互&#xff0c;但設備種類很多&#xff0c;各自有自己的接入規則&#xff01;傳…

    mysql索引:索引應該選擇哪種數據結構 B+樹 MySQL中的頁 頁主體 頁目錄 索引分類

    索引是什么?為什么要使用索引? 以前學數據結構時學了ArrayList,我們可以往里面存放數據 但是有問題,也就是說當程序重啟或是電腦關機之后,數據就沒有了,為什么? 因為他的數據是保存在內存中的 數據庫把數據保存在磁盤中,就可以完成對數據的持久化內存與外存的區別 內存&…

    SpringBoot靜態資源與緩存配置全解析

    springboot中靜態資源classpath就是resource文件夾下歡迎頁規則項目啟動默認去找靜態資源下的index.html頁面 默認訪問該頁面favicon原則在靜態資源目錄下尋找favicon.ico緩存實驗在請求中使用Cache-Control 時&#xff0c;它可選的值有&#xff1a;在響應中使用Cache-Control …

    基于 Python Django 和 Spark 的電力能耗數據分析系統設計與實現7000字論文實現

    摘要隨著能源問題日益突出&#xff0c;電力能耗數據分析對于提高能源利用效率、降低能源消耗具有重要意義。本文設計并實現了一個基于 Python Django 和 Spark 的電力能耗數據分析系統。系統采用前后端分離架構&#xff0c;前端使用 Django 框架實現用戶界面&#xff0c;后端使…

    elementUI vue2 前端表格table數據導出(二)

    為啥前端導出不在贅述了&#xff0c;不然讀者也難看到這篇文章。第一步&#xff1a;安裝依賴npm install vue-json-excel第二步&#xff1a;引用依賴配置// 導出Excel文件組件 import JsonExcel from vue-json-excel; Vue.component(downloadExcel, JsonExcel)第三步&#xff1…

    RabbitMQ 4.1.1-Local random exchange體驗

    Local Random Exchange 一種 RabbitMQ 4.0 引入的新型交換機&#xff0c;主要是為 request-reply&#xff08;RPC&#xff09;場景 設計的。 使用這種交換機時&#xff0c;消息只會被路由到本地節點上的隊列&#xff0c;可以確保極低的消息發布延遲。如果有多個本地隊列綁定到該…

    中山排氣歧管批量自動化智能化3D尺寸測量及cav檢測分析

    當前制造業快速發展&#xff0c;傳統測量方法正面臨嚴峻挑戰。生產規模的持續擴張使得現有測量手段逐漸暴露出效率不足的問題&#xff0c;這種技術滯后性正在直接影響企業的整體生產效率。具體表現為測量速度跟不上生產節拍&#xff0c;精度要求難以達標&#xff0c;最終導致生…

    Debian 11 Bullseye 在線安裝docker

    首先移除所有錯誤的 Docker 軟件源&#xff1a;sudo rm -f /etc/apt/sources.list.d/docker*安裝必要依賴sudo apt update sudo apt install -y ca-certificates curl gnupg添加 Docker 官方 GPG 密鑰&#xff08;使用國內鏡像&#xff09;&#xff1a;curl -fsSL https://mirr…

    Spring Boot 項目中多數據源配置使用場景

    在 Spring Boot 中配置多數據源是一個非常常見的需求&#xff0c;主要用于以下場景&#xff1a; 讀寫分離&#xff1a;一個主數據庫&#xff08;Master&#xff09;負責寫操作&#xff0c;一個或多個從數據庫&#xff08;Slave&#xff09;負責讀操作&#xff0c;以提高性能和可…