一、前言

  在IC前端设计/验证领域,只会HDL远远不够。目前大多数项目使用已开发好的系统架构和IP Core,因此设计部分的工作量慢慢向系统集成和验证方向转移。而在集成和验证过程中,往往以各种脚本和面向对象的高级语言为主要工具。SystemVerilog已成为主流验证语言,相当于VerilogHDL与C++的结合体。故掌握C++基础是十分必要的。

二、类封装示例及解读

  本文以《C++ Primer Plus》书中的一个简单的代码示例,讲讲自己对类封装的理解。出于练习、总结和记录的目的。OOP设计思想中:万物皆为某一类中的一个对象,类即为一群具有共性对象的抽象表示。每个类包含了数据成员和方法,成员是类包含的特性,而方法表示这一类的对象能完成哪些事情。以下示例描述的是股票这一类别。股票肯定包含股票数量和每股的价钱了。至于方法最起码可以买、卖,变动价格吧。

  一般将类声明、方法定义分别放置在class_name.h和class_name.cpp文件中。这样的做法正符合了“封装”、“细节隐藏”的思想,让应用程序无需关注实现细节,这一点与C语言一致。先来看看class_name.h文件中类声明。

 #ifndef STOCK00_H_
#define STOCK00_H_ #include <string> class Stock
{
private:
std::string m_company;
long m_shares;
double m_share_val;
double m_total_val;
void set_tot() {m_total_val = m_shares * m_share_val;}//内联函数
public:
//two constructors
Stock();//default constructor
Stock(const std::string &co,long n = ,double pr = 0.0);
//destructor
~Stock();
void acquire(const std::string &co,long n,double pr);
void buy(long num,double price);
void sell(long num,double price);
void update(double price);
void show() const;//promises not to change invoking object
const Stock &topval(const Stock &s) const;
}; #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 = ;
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<)
{
std::cout <<"Number of shares can't be negative;"
<< m_company << "shares set to 0.\n";
m_shares = ;
}
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<)
{
std::cout << "Number of shares can't be negative; "
<< m_company << "shares set to 0.\n";
m_shares = ;
}
else
m_shares = n;
m_share_val = pr;
set_tot();
} void Stock::buy(long num, double price)
{
if(num<)
{
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 < )
{
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指针会指向用来调用成员函数对象。

三、应用程序及结果分析

  应用程序代码如下:

 #include <iostream>
#include "stock00.h" const int STKS = ;
int main()
{
Stock stocks[STKS] = {//create object array of Stock class
Stock("NanoSmart",,20.0),
Stock("Boffo Objects",,2.0),
Stock("Monolithic Obelisks",,3.25),
Stock("Fleep Enterprises",,6.5)
}; std::cout << "Stock holdings:\n";
int st;
for (st=;st<STKS;st++)
{
stocks[st].show();//show informations
} //set top pointer to the first element
const Stock *top = &stocks[];
for(st=;st<STKS;st++)
{
top = &top ->topval(stocks[st]);
}
//now top points to the most valuable holding
std::cout <<"\nMost valuable holding:\n";
top->show();
return ;
}

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脚本等相关内容。

C++基础——类封装简单示例的更多相关文章

  1. 2016/11/17 周四 <javascript的封装简单示例>

    这是一个简单的javascript代码封装的示例以及封装后的调用方法: var ticker={ n:0, add:function() { this.n++; }, show:function() ...

  2. 3D开发基础知识和简单示例

    引言 现在物联网概念这么火,如果监控的信息能够实时在手机的客服端中以3D形式展示给我们,那种体验大家可以发挥自己的想象. 那生活中我们还有很多地方用到这些,如上图所示的Kinect 在医疗上的应用,当 ...

  3. 【Demo 0004】Java基础-类封装性

    本章学习要点:       1.  Java封装特性;       2.  掌握类的定义:       3.  掌握类的调用方法; 一.封装特性        Java 纯面向对象语言,面向对象语言遵 ...

  4. Python3基础 try-except-finally 的简单示例

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  5. Python3基础 三元运算符 简单示例

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  6. Python3基础 lambda表达式 简单示例

    镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...

  7. salesforce 零基础学习(四十八)自定义列表分页之Pagination基类封装 ※※※

    我们知道,salesforce中系统标准列表页面提供了相应的分页功能,如果要使用其分页功能,可以访问http://www.cnblogs.com/zero-zyq/p/5343287.html查看相关 ...

  8. 【JAVA零基础入门系列】Day12 Java类的简单应用

    俗话说的好,实践出真知,所以除了理论知识掌握扎实以外,更重要的是要多加操练,这样才能掌握核心科技. 今天我们就用刚学会的类来实践一下,目标便是完成上一篇中的剁手任务. 我们的商品类已经准备好了,代码重 ...

  9. Python自定义线程类简单示例

    Python自定义线程类简单示例 这篇文章主要介绍了Python自定义线程类,结合简单实例形式分析Python线程的定义与调用相关操作技巧,需要的朋友可以参考下.具体如下: 一. 代码     # - ...

随机推荐

  1. 怎么确定Oracle客户端安装成功

    可通过能否登录sqlplus来判断是否安装成功. 操作系统:windows10 oracle版本:oracle 11g 步骤: 1.电脑win键+R键,输入cmd,进入命令提示符. 2.命令行中输入: ...

  2. sniffer 软件的使用方法

    一.捕获数据包前的准备工作 在默认情况下,sniffer将捕获其接入碰撞域中流经的所有数据包,但在某些场景下,有些数据包可能不是我们所需要的,为了快速定位网络问题所在,有必要对所要捕获的数据包作过滤. ...

  3. 十七、Hadoop学记笔记————Hbase入门

    简而言之,Hbase就是一个建立在Hdfs文件系统上的数据库(mysql,orecle等),不同的是Hbase是针对列的数据库 Hbase和普通的关系型数据库区别如下: Hbase有一些基本的术语,主 ...

  4. 在centos,docker中安装HeadlessChrome

    在centos6中安装chrome与chrome-driver,中间走了很多弯路,遇到很多坑,现将详细步骤总结如下.参考博客链接:https://blog.csdn.net/u013849486/ar ...

  5. java语言为什么能跨平台

    参考https://blog.csdn.net/woailuo453786790/article/details/51660015 因为Java程序编译之后的代码不是能被硬件系统直接运行的代码,而是一 ...

  6. 【prufer编码+组合数学】BZOJ1005 [HNOI2008]明明的烦恼

    Description 自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Solution 这 ...

  7. 51nod_1412_AVL树的种类_动态规划

    51nod_1412_AVL树的种类_动态规划 题意: 平衡二叉树(AVL树),是指左右子树高度差至多为1的二叉树,并且该树的左右两个子树也均为AVL树. 现在问题来了,给定AVL树的节点个数n,求有 ...

  8. css:id选择器的权重>class选择器的权重=属性选择器的权重>元素选择器

    最近的项目要自己写前端了,重新学习下前端的一下基本知识. 一般在css样式表中,上面的会被下面的覆盖,如下图,文字会显示蓝色: 所以按照正常的来说,下面的css样式,测试的文字应该还是蓝色 但结果,测 ...

  9. 读取txt内文件内容

    命令如下: f = open("c:\\1.txt","r")  lines = f.readlines()#读取全部内容  for line in lines ...

  10. 用Fundebug插件记录网络请求异常

    在服务端,不管我们使用Node.js.Java.PHP还是Python等等,都会用日志以文本的形式记录请求以及报错信息.这个对于后端做事后分析是很有用的. 另一方面,前端有时候出问题其实是因为后端接口 ...