c++的類開發第一篇

来源:https://www.cnblogs.com/ivanlee717/p/18008529
-Advertisement-
Play Games

class_1 什麼是介面? 類就是一種公共介面,公眾(public)是使用類的程式,交互系統由類對象組成,而介面由編寫類的人提供的方法組成。介面讓程式員能夠編寫與類對象交互的代碼,從而讓程式能夠使用類對象。例如,要計算 string 對象中包含多少個字元,您無需打開對象,而只需使用string類提 ...


class_1

什麼是介面?

類就是一種公共介面,公眾(public)是使用類的程式,交互系統由類對象組成,而介面由編寫類的人提供的方法組成。介面讓程式員能夠編寫與類對象交互的代碼,從而讓程式能夠使用類對象。例如,要計算 string 對象中包含多少個字元,您無需打開對象,而只需使用string類提供的size()方法。類設計禁止公共用戶直接訪問類,但公眾可以使用方法size()。

oop風格

OOP(面向對象編程)是一種編程範式,它將程式組織為相互交互的對象。這種編程風格基於對象的概念,其中對象是通過封裝數據和操作數據的方法(即類中的成員函數)來表示的。

OOP 風格的編程主要關註以下幾個核心概念:

  1. 封裝(Encapsulation):將數據和對數據的操作封裝到一個類中,通過限制對數據的直接訪問來保護數據的完整性。只有類中定義的方法可以訪問和修改數據,外部無法直接訪問數據。
  2. 繼承(Inheritance):通過繼承機制,子類可以繼承父類的屬性和方法,並且可以在此基礎上進行擴展或修改。繼承可以提高代碼的重用性和可維護性。
  3. 多態(Polymorphism):多態允許對象根據所處的上下文環境以不同的方式進行操作。通過多態,可以通過基類指針或引用調用派生類中的方法,實現動態綁定和運行時多態性。
  4. 抽象(Abstraction):抽象是指從具體的事物中抽取出共同的特征和行為,形成類的概念。通過抽象,可以定義介面和基類,隱藏具體實現細節,提高代碼的可擴展性和靈活性。

OOP 風格的編程可以使代碼更具有模塊化、可維護性和可擴展性。它將現實世界中的事物和關係映射到程式設計中,使得代碼更貼近問題領域的語義,更易於理解和維護。

在使用 OOP 風格編程時,通常會定義類、對象、繼承關係和介面等概念來描述問題和解決方案。C++ 是一種支持面向對象編程的語言,並且提供了類、繼承、多態等特性以支持 OOP 風格的編程。

無論類成員是數據成員還是成員函數,都可以在類的公有部分或私有部分中聲明它。但由於隱藏數據是OOP主要的目標之一,因此數據項通常放在私有部分,組成類介面的成員函數放在公有部分:否則,就無法從程式中調用這些函數。正如Stock聲明所表明的,也可以把成員函數放在私有部分中。不能直接從程式中調用這種函數,但公有方法卻可以使用它們。通常,程式員使用私有成員函數來處理不屬於公有介面的實現細節。不必再類聲明的時候使用關鍵字private,因為這是類對象的預設訪問控制

頭文件的類聲明

在C++中,.h 文件通常是用於聲明類、函數、變數和其他代碼實體的頭文件(header file)。頭文件的作用是提供一種將程式的聲明與定義分離的機制,在不暴露實現細節的情況下,讓其他源文件可以訪問和使用這些聲明。

頭文件通常包含以下內容:

  1. 類的聲明:頭文件中可以包含類的聲明,包括成員變數和成員函數的原型(聲明)。
  2. 函數的聲明:頭文件可以包含函數的原型(聲明),使得其他源文件可以調用這些函數。
  3. 常量和巨集定義:頭文件中可以定義常量和巨集,以供其他源文件使用。
  4. 類型定義和類型別名:頭文件中可以進行類型定義和類型別名的聲明,以提供更具有可讀性和可維護性的代碼。

頭文件通常與對應的源文件(.cpp 文件)配合使用。源文件包含類的實現和函數的具體定義,而頭文件則包含對類和函數的聲明。通過包含頭文件,其他源文件可以在編譯時瞭解到需要使用的類、函數或常量的結構和介面,從而能夠正確地進行鏈接和調用。

為了避免頭文件被重覆包含造成編譯錯誤,通常會在頭文件的開頭添加預處理器指令,如下所示:

#ifndef HEADER_NAME_H
#define HEADER_NAME_H

// 頭文件內容

#endif

這些預處理器指令會檢查是否已定義頭文件的標識符(HEADER_NAME_H),如果沒有定義,則對頭文件進行包含,否則跳過頭文件的內容。這樣可以確保同一個頭文件不會被重覆包含。

總結來說,.h 文件是用於聲明類、函數、變數和其他代碼實體的頭文件,在編程中起到了提供介面和分離聲明與定義的作用。

#pragma once
#ifndef STOCK00_H_
#define STOCK00_H_

#include <string>
using namespace std;
class Stock {
private:
	string company;
	long shares;
	double share_val;
	double total_val;
	void set_total() {
		total_val = shares * share_val;
	}
public:
	void acquire(const string& co, long n, double pr);
    /*const string& co 中的 & 符號表示該參數是一個引用。使用引用作為函數參數可以避免在函數調用時進行額外的拷貝操作,提高了性能和效率。

const 關鍵字表示對傳入的 co 參數進行只讀操作,即在函數內部不會修改該參數的值。這樣設計是為了保證在函數調用中不會無意間修改傳入的字元串對象。

將參數聲明為引用類型有以下幾個優點:

避免了不必要的拷貝:如果不使用引用,而是直接傳遞 string 對象作為參數,那麼在函數調用時會進行一次拷貝操作,將實參的值複製給形參。對於較大的字元串,拷貝操作可能會帶來較大的開銷,使用引用可以避免這種開銷。
可以修改傳入的對象:雖然在這個例子中 co 被聲明為 const 引用,不可修改,但通常情況下,如果不使用 const 修飾符,函數可以通過引用修改傳入的對象的值,從而達到傳入參數的輸出效果。
簡化函數調用語法:使用引用作為參數類型時,可以直接傳遞對象而無需取地址或者使用指針。這樣可以簡化函數調用的語法,使代碼更加簡潔。
綜上所述,使用 const string& 作為函數參數類型可以提高性能和效率,並且在函數調用時更加方便和簡潔。*/
	void buy(long num, double price);
	void sell(long num, double price);
	void update(double price);
	void show();
};

#endif
  1. 定義成員函數時,使用作用域解析運算符(::)來標識函數所屬的類;
  2. 類方法可以直接訪問類的private組件
#include<iostream>
using namespace std;
#include "stock00.h"

void Stock::acquire(const string& co, long n, double pr) {
	company = co;
	if (n < 0) {
		cout << "number of shares can not be negative; "
			<< company << "shares set to 0\n";
	}
	else {
		shares = n;
	}
	share_val = pr;
	set_total();

}

void Stock::buy(long num, double price) {
	if (num < 0) {
		cout << "number of shares purchased can not be negative. "
			<< "transaction is abouted. \n";
	}
	else {
		shares += num;
		share_val = price;
		set_total();
	}
}

void Stock::sell(long num, double price) {
	if (num < 0) {
		cout << "number of shares sold can not be negative. "
			<< "transaction is abouted. \n";
	}
	else if (num > shares) {
		cout << "you can not sell more than you have! "
			<< "transaction is abouted. \n";
	}
	else {
		shares -= num;
		share_val = price;
		set_total();
	}
}

void Stock::update(double price) {
	share_val = price;
	set_total();
}

void Stock::show() {
	cout << "Company: " << company
		<< "Shares: " << shares << '\n'
		<< "Share Price: $" << share_val
		<< "Total Worth: $" << total_val << endl;
}

這樣子對於一個類的聲明和方法都已經寫好了。其實簡單一點也能放在一起寫,但是這樣寫更符合開發習慣。

//useStock.cpp
#include<iostream>
using namespace std;
#include "stock00.h"

int main() {
	Stock regina;
	regina.acquire("ivanlee", 20, 12.5);
	regina.show();
	regina.buy(20, 12.7);
	regina.show();
	regina.sell(400, 20);
	regina.show();
	regina.buy(127717, 40.127);
	regina.show();
	regina.sell(127717, 40.128);
	regina.show();
	return 0;
}

image-20240205153233564

但是這個科學計數法讓我們不知道具體數字,可以定義cout.setf(ios_base::fixed, ios_base::floatfield);

image-20240205153613587

普通設置一個類

設計立方體類(Cube),求出立方體的面積( 2ab + 2ac + 2bc )和體積( a * b * c),分別用全局函數和成員函數判斷兩個立方體是否相等image-20240205153715533基本類的使用就算是明白了

#include<iostream>
using namespace std;
class Cube {
private:
	double high;
	double wid;
	double length;
public:
	void set_high(double n) { high = n; }
	void set_wid(double n) { wid = n; }
	void set_length(double n) { length = n; }
	double get_high() { return high; }
	double get_wid() { return wid; }
	double get_length() { return length; }
	double calculate_V() { return high * wid * length; }
	double calculate_S() { return 2 * (high * wid + high * length + wid * length); }
	bool Compare_V(Cube C) {
		if (C.calculate_V() == calculate_V()) {
			return true;
		}
		return false;
	}
	bool Compare_S(Cube C) {
		if (C.calculate_S() == calculate_S()) {
			return true;
		}
		return false;
	}

};

bool compare_V(Cube a, Cube b) {
	if (a.calculate_V() == b.calculate_V()) {
		return true;
	}
	else { return false; }
}
bool compare_S(Cube a, Cube b) {
	if (a.calculate_S() == b.calculate_S()) {
		return true;
	}
	else { return false; }
}

int main() {
	Cube regina;
	Cube ivan;
	regina.set_high(1);
	regina.set_length(2);
	regina.set_wid(7);
	ivan.set_high(1);
	ivan.set_length(7);
	ivan.set_wid(7);

	if (ivan.Compare_S(regina)) {
		cout << "ivan_S" << endl;
	}
	else {
		cout << "regina_S" << endl;
	}
	if (regina.Compare_V(ivan)) {
		cout << "regina_V" << endl;
	}
	else {
		cout << "ivan_V" << endl;
	}
	return 0;	
}

本文來自博客園,作者:ivanlee717,轉載請註明原文鏈接:https://www.cnblogs.com/ivanlee717/p/18008529


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

-Advertisement-
Play Games
更多相關文章
  • 一、java鎖存在的必要性 要認識java鎖,就必須對2個前置概念有一個深刻的理解:多線程和共用資源。 對於程式來說,數據就是資源。 在單個線程操作數據時,或快或慢不存在什麼問題,一個人你愛乾什麼乾什麼。 多個線程操作各自操作不同的數據,各乾各的,也不存在什麼問題。 多個線程對共用數據進行讀取操作, ...
  • 讀了啥 周志明的深入理解Java虛擬機中的調優案例。 第一個案例 背景 一個網站部署在JVM上,而Java堆大小固定在了12G,但是總會出現長時間無法響應的情況。 使用了吞吐量優先收集器:可能是Parallel Scavenge和Parallel Old收集器。 問題 網站直接從磁碟拷貝文檔到堆記憶體 ...
  • 電腦網路作為一門電腦專業課,平時都是各種抽象的協議和各種發送接收,很難具體的去感受其含義,因此也是藉助wireshark對發送的包進行一個分析。 ...
  • 大家好,我是你們的老伙計秀才!今天帶來的是[深入淺出Java多線程]系列的第九篇內容:synchronized與鎖。大家覺得有用請點贊,喜歡請關註!秀才在此謝過大家了!!! ...
  • 本文全面深入地探討了對象存儲服務(OSS)的核心技術、基礎知識和高級功能。從媒體存儲到數據備份,再到數據倉庫與數據湖,我們不僅解析了OSS在各種應用場景下的關鍵角色,還深入討論了其與機器學習、多媒體處理以及日誌和監控等多個開發場景的結合。 關註【TechLeadCloud】,分享互聯網架構、雲服務技 ...
  • 通過本文,我們使用Python編寫了一個簡單的日曆程式。在Python官方文檔中,我們找到了一個名為"calendar"的模塊,它可以輕鬆實現一個簡易的日曆,滿足基本需求。此外,我們還介紹了Tkinter和PyQt兩個常用的圖形用戶界面庫,以及borax庫和其他一些開源項目來實現更多功能和用戶體驗的... ...
  • wmproxy wmproxy已用Rust實現http/https代理, socks5代理, 反向代理, 負載均衡, 靜態文件伺服器,websocket代理,四層TCP/UDP轉發,內網穿透等,會將實現過程分享出來,感興趣的可以一起造個輪子 項目地址 國內: https://gitee.com/ti ...
  • 1. 我遇到了什麼問題 我在學習springboot,其中在編寫CRUD時發現訪問數據的函數執行下去返回值是null但是其它部分正常。 下麵是我的錯誤代碼 pojo public class Bot { @TableId(type = IdType.AUTO ) private Integer id ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...