一、前言

  在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. Javassist字节码增强示例

    概述 Javassist是一款字节码编辑工具,可以直接编辑和生成Java生成的字节码,以达到对.class文件进行动态修改的效果.熟练使用这套工具,可以让Java编程更接近与动态语言编程. 下面一个方 ...

  2. XamarinForm Effects 调用事件

    原文地址 在Xamarin.Forms控件中实现底层多点触控跟踪. 一个effect可以定义和调用一个事件,在底层本地视图中发出信号的变化.这篇文章演示如何实现底层多点触控跟踪,以及如何生成信号触摸活 ...

  3. D. Kuro and GCD and XOR and SUM

    Kuro is currently playing an educational game about numbers. The game focuses on the greatest common ...

  4. RecyclerView android

    RecyclerView是用来替代ListView.GridView的一个牛掰的控件.用起来更灵活,还能实现线性布局(横向.纵向).网格布局.瀑布流等美观的UI. 在使用RecyclerView时候, ...

  5. linux,windows下检测指定的IP地址是否可用或者检测IP地址冲突的3种方式(批处理程序,python程序,linux shell 批量ping)

    本文中的脚本适用范围: 1)检测某些IP地址是否被占用: 2)检测网络中某些设备是否存活: 3)在分配新的ip地址之前,批量检测环境中是否存在冲突的机器 以上检测基于ICMP Ping报文,要求所有的 ...

  6. JavaScript 异步开发全攻略(转)

    写了一本介绍 JavaScript 异步开发的小书: https://meathill.gitbooks.io/javascript-async-tutorial/content/ 除了比较详细的介绍 ...

  7. MongoDB之DBref(关联插入,查询,删除) 实例深入

    http://blog.csdn.net/crazyjixiang/article/details/6668288 suppose I have the following datastructure ...

  8. 自动化测试基础二(Python基础)

    1.为什么学习Python 1)简单.易学 2)强大:交互性.解释性.编译性.跨平台 3)市场需求上升快.顺应市场需要 4)自动化测试需要使用编程语言来写脚本 2.需要学习Python哪些内容? 1) ...

  9. 绕过token

    网站搭好了,下一步的目标就是直奔后台.因为一般前端在未登录的情况下只有查的功能.咱们的目标是增删改. 看到有添加功能时,先别着急的直接黑盒测试.先看看有没有防护 ######## 查看源码,搜索tok ...

  10. float_array.go

    )         if err != nil {             log.Fatalf("Could not parse: %s", s)             ret ...