C++基础——类封装简单示例
一、前言
在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++基础——类封装简单示例的更多相关文章
- 2016/11/17 周四 <javascript的封装简单示例>
这是一个简单的javascript代码封装的示例以及封装后的调用方法: var ticker={ n:0, add:function() { this.n++; }, show:function() ...
- 3D开发基础知识和简单示例
引言 现在物联网概念这么火,如果监控的信息能够实时在手机的客服端中以3D形式展示给我们,那种体验大家可以发挥自己的想象. 那生活中我们还有很多地方用到这些,如上图所示的Kinect 在医疗上的应用,当 ...
- 【Demo 0004】Java基础-类封装性
本章学习要点: 1. Java封装特性; 2. 掌握类的定义: 3. 掌握类的调用方法; 一.封装特性 Java 纯面向对象语言,面向对象语言遵 ...
- Python3基础 try-except-finally 的简单示例
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- Python3基础 三元运算符 简单示例
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- Python3基础 lambda表达式 简单示例
镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...
- salesforce 零基础学习(四十八)自定义列表分页之Pagination基类封装 ※※※
我们知道,salesforce中系统标准列表页面提供了相应的分页功能,如果要使用其分页功能,可以访问http://www.cnblogs.com/zero-zyq/p/5343287.html查看相关 ...
- 【JAVA零基础入门系列】Day12 Java类的简单应用
俗话说的好,实践出真知,所以除了理论知识掌握扎实以外,更重要的是要多加操练,这样才能掌握核心科技. 今天我们就用刚学会的类来实践一下,目标便是完成上一篇中的剁手任务. 我们的商品类已经准备好了,代码重 ...
- Python自定义线程类简单示例
Python自定义线程类简单示例 这篇文章主要介绍了Python自定义线程类,结合简单实例形式分析Python线程的定义与调用相关操作技巧,需要的朋友可以参考下.具体如下: 一. 代码 # - ...
随机推荐
- Javassist字节码增强示例
概述 Javassist是一款字节码编辑工具,可以直接编辑和生成Java生成的字节码,以达到对.class文件进行动态修改的效果.熟练使用这套工具,可以让Java编程更接近与动态语言编程. 下面一个方 ...
- XamarinForm Effects 调用事件
原文地址 在Xamarin.Forms控件中实现底层多点触控跟踪. 一个effect可以定义和调用一个事件,在底层本地视图中发出信号的变化.这篇文章演示如何实现底层多点触控跟踪,以及如何生成信号触摸活 ...
- D. Kuro and GCD and XOR and SUM
Kuro is currently playing an educational game about numbers. The game focuses on the greatest common ...
- RecyclerView android
RecyclerView是用来替代ListView.GridView的一个牛掰的控件.用起来更灵活,还能实现线性布局(横向.纵向).网格布局.瀑布流等美观的UI. 在使用RecyclerView时候, ...
- linux,windows下检测指定的IP地址是否可用或者检测IP地址冲突的3种方式(批处理程序,python程序,linux shell 批量ping)
本文中的脚本适用范围: 1)检测某些IP地址是否被占用: 2)检测网络中某些设备是否存活: 3)在分配新的ip地址之前,批量检测环境中是否存在冲突的机器 以上检测基于ICMP Ping报文,要求所有的 ...
- JavaScript 异步开发全攻略(转)
写了一本介绍 JavaScript 异步开发的小书: https://meathill.gitbooks.io/javascript-async-tutorial/content/ 除了比较详细的介绍 ...
- MongoDB之DBref(关联插入,查询,删除) 实例深入
http://blog.csdn.net/crazyjixiang/article/details/6668288 suppose I have the following datastructure ...
- 自动化测试基础二(Python基础)
1.为什么学习Python 1)简单.易学 2)强大:交互性.解释性.编译性.跨平台 3)市场需求上升快.顺应市场需要 4)自动化测试需要使用编程语言来写脚本 2.需要学习Python哪些内容? 1) ...
- 绕过token
网站搭好了,下一步的目标就是直奔后台.因为一般前端在未登录的情况下只有查的功能.咱们的目标是增删改. 看到有添加功能时,先别着急的直接黑盒测试.先看看有没有防护 ######## 查看源码,搜索tok ...
- float_array.go
) if err != nil { log.Fatalf("Could not parse: %s", s) ret ...