C++基礎——類封裝簡單示例

来源:https://www.cnblogs.com/moluoqishi/archive/2019/04/11/10692284.html
-Advertisement-
Play Games

一、前言 在IC前端設計/驗證領域,只會HDL遠遠不夠。目前大多數項目使用已開發好的系統架構和IP Core,因此設計部分的工作量慢慢向系統集成和驗證方向轉移。而在集成和驗證過程中,往往以各種腳本和麵向對象的高級語言為主要工具。SystemVerilog已成為主流驗證語言,相當於VerilogHDL ...


一、前言

  在IC前端設計/驗證領域,只會HDL遠遠不夠。目前大多數項目使用已開發好的系統架構和IP Core,因此設計部分的工作量慢慢向系統集成和驗證方向轉移。而在集成和驗證過程中,往往以各種腳本和麵向對象的高級語言為主要工具。SystemVerilog已成為主流驗證語言,相當於VerilogHDL與C++的結合體。故掌握C++基礎是十分必要的。

二、類封裝示例及解讀

  本文以《C++ Primer Plus》書中的一個簡單的代碼示例,講講自己對類封裝的理解。出於練習、總結和記錄的目的。OOP設計思想中:萬物皆為某一類中的一個對象,類即為一群具有共性對象的抽象表示。每個類包含了數據成員和方法,成員是類包含的特性,而方法表示這一類的對象能完成哪些事情。以下示例描述的是股票這一類別。股票肯定包含股票數量和每股的價錢了。至於方法最起碼可以買、賣,變動價格吧。

  一般將類聲明、方法定義分別放置在class_name.h和class_name.cpp文件中。這樣的做法正符合了“封裝”、“細節隱藏”的思想,讓應用程式無需關註實現細節,這一點與C語言一致。先來看看class_name.h文件中類聲明。

 1 #ifndef STOCK00_H_
 2 #define STOCK00_H_
 3 
 4 #include <string>
 5 
 6 class Stock
 7 {
 8 private:
 9     std::string m_company;
10     long m_shares;
11     double m_share_val;
12     double m_total_val;
13     void set_tot() {m_total_val = m_shares * m_share_val;}//內聯函數
14 public:
15     //two constructors
16     Stock();//default constructor
17     Stock(const std::string &co,long n = 0,double pr = 0.0);
18     //destructor
19     ~Stock();
20     void acquire(const std::string &co,long n,double pr);
21     void buy(long num,double price);
22     void sell(long num,double price);
23     void update(double price);
24     void show() const;//promises not to change invoking object
25     const Stock &topval(const Stock &s) const;
26 };
27 
28 #endif
stock00.h

   Stock類聲明中包含了兩個最常用的訪問控制關鍵字pritive和public。class與C語言中結構體類似,只不過結構體數據成員均為public。pritive部分只能通過共有成員函數訪問。m_company m_shares m_share_val和m_total_val分別代表公司名稱、股票數量、股票單價以及總價。其中set_tot()為定義在類聲明中的成員函數,稱之為內聯函數。該函數只能被公有成員函數調用。

  公有成員函數acquaire buy sell update show和topval依次完成公司首次持股、買股票、賣股票、股價變動、顯示某公司股票信息以及尋找兩公司股票總價最高者的操作。有兩類比較特殊的函數:構造函數Stock()和析構函數~Stock()。前者負責類對象的初始化,析構函數則是逆向操作,用於對象銷毀時的清理工作,如釋放動態分配記憶體等。

  類方法定義:

#include <iostream>
#include "stock00.h"

Stock::Stock()
{
    std::cout << "Default constructor called.\n";
    m_company = "no name";
    m_shares = 0;
    m_share_val = 0.0;
    m_total_val = 0.0;
}

Stock::Stock(const std::string &co,long n,double pr)
{
    std::cout << "Constructor using " << co << " called\n";
    m_company = co;

    if(n<0)
    {
        std::cout <<"Number of shares can't be negative;"
            << m_company << "shares set to 0.\n";
        m_shares = 0;
    }
    else
        m_shares = n;
    m_share_val = pr;
    set_tot();
}

Stock::~Stock()
{
    std::cout << "Bye, " << m_company << "!\n";
}

void Stock::acquire(const std::string &co,long n,double pr)
{
    m_company = co;
    if(n<0)
    {
        std::cout << "Number of shares can't be negative; "
                  << m_company << "shares set to 0.\n";
        m_shares = 0;
    }
    else
        m_shares = n;
    m_share_val = pr;
    set_tot();
}

void Stock::buy(long num, double price)
{
    if(num<0)
    {
        std::cout << "Number of shares purchased can't be negative."
                   << "Transcation is aborted.\n";
    }
    else
    {
        m_shares += num;
        m_share_val = price;
        set_tot();
    }
}

void Stock::sell(long num,double price)
{
    using std::cout;
    if(num < 0)
    {
        cout << "Number of shares sold can't be negative. "
             << "Transcation is aborted.\n";
    }
    else if(num > m_shares)
    {
        cout <<"You can't sell more than you have! "
             << "Transcation is aborted.\n";
    }
    else 
    {
        m_shares -=num;
        m_share_val = price;
        set_tot();
    }
}

void Stock::update(double price)
{
    m_share_val = price;
    set_tot();
}

void Stock::show() const
{
    std::cout << "Company: " << m_company << " Shares:  " << m_shares << '\n'
              << "share Price:$" << m_share_val << " total worth:$" << m_total_val<< std::endl;
}
//選擇總價最高的股票,返回該股票
const Stock & Stock::topval(const Stock &s) const
{
    if(s.m_total_val > m_total_val)
        return s;
    else
        return *this;
}
stock00.cpp

  為了清晰看到構造和析構函數的隱式調用,使用cout列印相關信息。可以看到涉及到股價變動的操作時,均會調用set_tot()函數更新總股價。show()和topval()兩個函數後有“const”標識符,表明兩者是const成員函數。這種方式可以顯示告知編譯器:該函數不會改變傳輸實參。否則創建const類對象,且該對象調用show()函數時會報錯。topval函數中返回的this指針會指向用來調用成員函數對象。

三、應用程式及結果分析

  應用程式代碼如下:

 1 #include <iostream>
 2 #include "stock00.h"
 3 
 4 const int STKS = 4;
 5 int main()
 6 {
 7     Stock stocks[STKS] = {//create object array of Stock class
 8         Stock("NanoSmart",12,20.0),
 9         Stock("Boffo Objects",200,2.0),
10         Stock("Monolithic Obelisks",130,3.25),
11         Stock("Fleep Enterprises",60,6.5)
12     };
13 
14     std::cout << "Stock holdings:\n";
15     int st;
16     for (st=0;st<STKS;st++)
17     {
18         stocks[st].show();//show informations
19     }
20 
21     //set top pointer to the first element
22     const Stock *top = &stocks[0];
23     for(st=1;st<STKS;st++)
24     {
25         top = &top ->topval(stocks[st]);
26     }
27     //now top points to the most valuable holding
28     std::cout <<"\nMost valuable holding:\n";
29     top->show();
30     return 0;
31 }
usestock0.cpp

  親切的main函數終於現身了!這裡首先創建了一個Stock類的對象組成的數據stocks。其每個元素使用了顯示方式調用構造函數。作為Stock類的對象stocks[0]-stock[3]自然可以調用類方法。之後stocks[st].show()處列印每隔公司的股票信息。接著找出總股價最高的公司,並顯示信息信息。由於topval()函數僅能兩兩比較,故利用for迴圈找出最大者。精華都在這一句:top = &top ->topval(stocks[st]); 意思是:Stock類的指針top指向的Stock類對象與實參對象中總股價最大者的地址更新top。(確實有點繞)

  最後看看列印結果:

  列印結果表明,topval()函數成功索引到總股價最高的公司:Monolithic Obelisks。top->show()函數列印出其詳細信息。最後列印了類對象數組元素對應的bye信息,證明析構函數被隱式調用。後續會在軟體_腳本專欄中繼續講述C++基礎示例、Linux Shell腳本等相關內容。


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

-Advertisement-
Play Games
更多相關文章
  • 原文使用的是python2,現修改為python3,全部都實際輸出過,可以運行。 引用自:http://www.cnblogs.com/duyaya/p/8562898.html https://blog.csdn.net/cv_you/article/details/70880405 python ...
  • 棧:後進先出(LIFO)表。 特點:只允許在頂部進行存取操作的順序表。 基本操作: push:入棧,即將元素壓入棧頂 pop:出棧,即將棧頂元素刪除 top:輸出棧頂元素 應用場景: 平衡符號:編譯器中用於檢查符號是否成對出現,方法為做一個空棧,讀取字元,如果字元是一個開放符號如“{”、“(”、“[ ...
  • 今天來繼續學習一下Numpy庫的使用 接著昨天的內容繼續 在Numpy中,我們如果想要進行一個判斷使用“==” 我們來看下麵的代碼 我們來看看上面的代碼,這段代碼表示的是什麼意思呢? vector == 10 表示的是,當前的array當中所有的元素都會進行判斷 是否等於10 我們可以看到,運行結果 ...
  • 程式在記憶體中的存儲分為三個區域,分別是動態數據區、靜態數據區和代碼區。函數存儲在代碼區,全局變數以及靜態變數存儲在靜態數據區,而在程式執行的時候才會在動態數據區產生數據。程式執行的本質就是代碼區的指令不斷執行,驅使動態數據區和靜態數據區產生數據變化。 代碼區與動態數據區由三個寄存器控制,分別是eip ...
  • 在JDK1.2以後將對象應用分為4中,強引用,軟引用,弱引用,虛引用,這樣的方式可以更加靈活控制對象的聲明周期 強引用 String str = "123"; 這時我們日常用的引用,只要對象與強引用關聯,如果記憶體不足時,JVM寧願拋出OutOfMemoryError記憶體溢出錯誤也不會回收強引用 如果 ...
  • 完全個人總接 每個文件頭部都可以加入這個,或者放到用單獨一個文件,再import *。其實都一樣,只需要一行false=False;true=True;none=null=None;hid=lambda o:"0x%X"%id(o) 作用:可以像多數語言一樣用小寫的關鍵字,布爾:false/true ...
  • gin作為go語言最知名的網路庫,在這裡我簡要介紹一下url的查詢參數解析。主要是這裡面存在一些需要註意的地方。這裡,直接給出代碼,和運行結果,在必要的地方進行分析。 代碼1: 測試結果: 輸出結果: curl "http://localhost:8080/getb?field_a=hello&fi ...
  • (1)String是字元串常量,一旦創建之後不可更改;StringBuffer和StringBuilder是字元串變數,可以更改。String的不可變,所以適合作為Map的鍵。 (2)StringBuilder 是線程不安全的,StringBuffer是線程安全的,使用了Synchronized關鍵 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...