C++ 学习笔记(五)类的知识小结一(重载,友元函数,静态成员,new)
---恢复内容开始---
学习C++类知识点还是挺多的,每个知识点学习的时候都觉得这个知识点咋那么多东西,其实真学完了再回头看好像也就那么点。这次用程序写一个黑猫揍白猫的故事总结一下这段时间学习的零碎知识点。包括以下几点:
1.重载:函数重载 、运算符重载
2.友元函数
3.静态成员变量
4.new / delete 关键字和 malloc / free函数的区别
程序将实现一个Cat类,定义一只黑猫一只白猫。用户喂食黑猫为黑猫增加武力值,之后用户给白猫喂食,为白猫增加生命值,两只猫都喂食完后黑猫就揍白猫一次。等到白猫生命值为0时或者食物喂完了程序结束(原谅我想不到更好的、又简单、又能符合想记录的知识点需求 的故事,只能无厘头的让白猫一直挨揍了)。。。
Cat类的定义:Cat.h
#pragma once
#include <iostream>
#include <string> #define CAT_ATTRIBUTE 1 #define FORCE_MAX 100
#define HP_MAX 100 #define CAT_MALE 1+CAT_ATTRIBUTE
#define CAT_FEMALE 2+CAT_ATTRIBUTE using namespace std; class Cat
{
/*公有成员:此类的对象可以直接使用*/
public:
static int food; //静态成员变量 Cat(string name ,int sex = CAT_MALE); //构造函数,创建一个对象时自动调用
Cat(string name ,int sex , unsigned int force_value = ); //函数的重载
~Cat(); //析构函数,没有返回值没有传参,delete对象时自动调用 int add_hp(int add_value); //普通成员函数
void report_state(); //普通成员函数
int get_hp();
int eat_food(int value);
friend unsigned int add_force(Cat *cat,int add_value); //友元函数(全局函数可访问类的私有成员) int operator-(Cat *cat); //- 运算符重载
int operator--(); //前置-- 运算符重载
int operator--(int); //后置-- 运算符重载(使用占位参数说明是后置运算符重载) /*私有成员:只能通过本类的公有函数和友元函数进行读写*/
private:
string name;
int sex; //性别
int HP; //生命值
unsigned int force_value; //武力值 };
Cat类的实现:Cat.cpp
#include "cat.h" int Cat::food = ; //初始化静态变量
Cat::Cat(string name ,int sex) //构造函数,创建一个对象时自动调用
{
/*设置初始值*/
this->name = name;
this->sex = sex;
this->HP = ;
this->force_value = ;
/*打印状态*/
cout<<" creat a new cat !! "<<endl;
this->report_state();
} Cat::Cat(string name ,int sex , unsigned int force_value ) //构造函数,创建一个对象时自动调用
{
/*设置初始值*/
this->name = name; this->sex = sex;
this->HP = ;
this->force_value = force_value;
/*打印状态*/
cout<<" creat a new cat !! "<<endl;
this->report_state(); } Cat::~Cat()//析构函数,没有返回值没有传参,delete对象时自动调用
{
cout<<"cat "<<this->name<<" was dead"<<endl;
} void Cat::report_state()
{
cout<< " ---------I am "<<this->name<<"----------" <<endl;
cout<< "my hp :"<<this->HP<<endl;
cout<< "my force value:"<<this->force_value<<endl;
cout<<"-------------------------------------"<<endl;
} int Cat::add_hp(int add_value)
{
this->HP += add_value;
return this->HP;
} int Cat::operator-(Cat *cat)//- 运算符重载
{
cat->HP -= this->force_value;
if(cat->HP < )
cat->HP = ;
cout<<this->name<<" hit - > "<<cat->name<<endl;
return cat->HP;
} int Cat::operator--()//前置-- 运算符重载
{
if(this->HP > )
this->HP -=;
return this->HP;
} int Cat::operator--(int)//后置-- 运算符重载(使用占位参数说明是后置运算符重载)
{
int temp = this->HP;
if(this->HP > )
this->HP -=; return temp;
} int Cat::get_hp()
{
return this->HP;
} int Cat::eat_food(int value)//将减少静态成员变量food的值
{
food -= value;
if(Cat::food<){
cout<<"food is used up !!"<<endl;
Cat::food = ;
}
return Cat::food;
} /*友元函数 可以通过传入对象 操作其私有属性*/
unsigned int add_force(Cat *cat,int add_value)
{
cat->force_value += add_value;
if(cat->force_value > FORCE_MAX)
cat->force_value = FORCE_MAX;
return cat->force_value;
}
main函数:main.cpp
#include <iostream>
#include <string>
#include "cat.h" using namespace std;
int main(int argc, char **argv)
{
int add_value = ;
Cat black("black",CAT_MALE,); //黑猫出生(调用构造函数)
Cat* white;
white = new Cat("white"); //白猫出生( 函数重载;new将分配堆中的内存,使用完毕需要delete) black--; //黑猫作死,扣一点血(后置--运算符重载)
cout<<"black cat's HP :"<<black.get_hp()<<endl; --*white; //白猫学黑猫作死,扣一点血(前置--运算符重载)
cout<<"white cat's HP:"<<white->get_hp()<<endl; /*如果黑猫白猫都还活着并且还有食物程序继续运行*/
while(black.get_hp() > && white->get_hp()> &&Cat::food )
{
cout<<"How much food do you want to feed for black cat "<<endl;
cin>>add_value;
black.eat_food(add_value);
cout<<"black's force :"<<add_force(&black,add_value)<<"\n"<<endl; //调用友元函数添加黑猫武力值 cout<<"How much food do you want to feed for white cat "<<endl;
cin>>add_value;
white->eat_food(add_value); //将减少静态成员food的值,这个food是整个Cat类共享的
cout<<"white's hp :"<<white->add_hp(add_value)<<"\n"<<endl; black-white; //‘-’运算符重载的使用
cout<<"white cat's HP"<<white->get_hp()<<endl;
cout<<"food still have "<<Cat::food<<endl;
} white->report_state();
black.report_state();
delete white; //使用new分配的内存需要释放
system("pause");
return ;
}
运行结果:
知识点总结:
1.函数重载 、参数默认值
本次例程中实现了两个Cat构造函数,传入参数不同
a.定义
Cat(string name ,int sex = CAT_MALE); //构造函数,创建一个对象时自动调用
Cat(string name ,int sex , unsigned int force_value = 20); //函数的重载
函数重载的判断标准是传参:传参的个数,传参的类型。
返回值不能作为函数重载的标准,即传参一样返回值类型不同的是会被认为函数重定义的。
b.使用
在main函数9行,定义black 的时候传入了三个参数很明显是调用了
Cat(string name ,int sex , unsigned int force_value = 20);
在new一个white的时候只传入了一个参数,其实调用了
Cat(string name ,int sex = CAT_MALE);
在Cat.h文件中我们可以看到sex = CAT_MALE;当没有传参的时候便使用这个默认参数。
而从黑猫的创建中因为传入force_value = 10,所以默认的20失效。
2.运算符重载
本例程重载了-、后置--、前置-- 三个运算符。运算符重载其实也是实现函数,只是函数名比较固定。友元函数可以访问私有成员,所以友元函数也能实现运算符重载,本例程使用成员函数进行运算符重载。
运算符重载的语法:
返回值类型 类名 :: operator op (参数)(operator是运算符重载关键字,op是要重载的运算符。)
后置---与前置--的区分方式在于后置--有int占位参数(利用C++函数重载的特性)
int Cat::operator-(Cat *cat)//- 运算符重载 int Cat::operator--() //前置-- 运算符重载 int Cat::operator--(int) //后置-- 运算符重载(使用占位参数说明是后置运算符重载)
一元重载:
个人理解是操作的对象只有一个,前置--和后置--属于一元重载,在重载函数实现中使用this指针既可以操作相应的成员
后置-- 和 前置-- 函数名是一样的。不同的是后置运算符重载有一个占位传参,这是编译器分辨这是前置还是后置运算符重载的标志。
二元重载:
操作对象有两个,‘-’ 运算符重载属于二元重载。
例如:
50 int Cat::operator-(Cat *cat)//- 运算符重载
51 {
52 cat->HP -= this->force_value;
53 if(cat->HP < 0)
54 cat->HP = 0;
55 cout<<this->name<<" hit - > "<<cat->name<<endl;
56 return cat->HP;
57 }
a-b;
此时在函数实现中,this指针操作的变量属于a,b则作为重载函数的传参。
2.友元函数
友元函数就是可以操作对象私有属性的函数。只要在类的定义中声明即可。
使用 friend 关键字,这个函数不是这个类的成员函数而是一个全局函数,可以通过传入参数cat来操作其私有成员,如果不是友元函数就算传入对象也不能操作其私有成员。
3.静态成员变量
静态成员变量是一个类所有对象共享的参数(个人理解成一个类的全局变量),本例程中Cat::food 就是静态成员变量,黑猫和白猫调用eat_food函数是两个不同对象操作了food成员,food减少了两次。
静态成员的定义:
1.先在定义类的时候声明
2.在C文件中给一个初始值
访问静态成员可以使用以下两种方法:
例:
Cat a("a");
a.food = 100;
Cat::food = 100;
4.new / delete 关键字和 malloc / free函数的区别
在本次例程中使用了两种创建对象的方法
使用new产生的是一个指针,之后操作white都是使用指针操作。
white是指针,使用前置-- 要先解引用(*white),如果没有解引用指针white就指到天南地北去了。
new创建的对象将分配堆的内存,与malloc一样。new也可以用于创建数组,变量等数据结构,malloc能做的事情new都能做。
malloc和new的那些事:
1.都是分配堆内存,使用完毕后需要释放
2.如果分配基础数据结构(暂时实验了除了类之外),malloc/free 、new/delete是可以互换的。即new出来的变量可以使用free释放,malloc的变量可以使用delete释放
3.分配类时,new将会调用构造函数,delete调用析构函数,所以创建类的时候不能使用malloc和free。
---恢复内容结束---
C++ 学习笔记(五)类的知识小结一(重载,友元函数,静态成员,new)的更多相关文章
- python学习笔记(五):装饰器、生成器、内置函数、json
一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里 ...
- (转)Qt Model/View 学习笔记 (五)——View 类
Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...
- Typescript 学习笔记五:类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- java之jvm学习笔记五(实践写自己的类装载器)
java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- ES6学习笔记<五> Module的操作——import、export、as
import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...
- muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor
目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...
- python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍
python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍 IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.pycharm免费社区版.Su ...
- 【opencv学习笔记五】一个简单程序:图像读取与显示
今天我们来学习一个最简单的程序,即从文件读取图像并且创建窗口显示该图像. 目录 [imread]图像读取 [namedWindow]创建window窗口 [imshow]图像显示 [imwrite]图 ...
随机推荐
- Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器
---视图 ---视图的概念:视图就是提供一个查询的窗口,来操作数据库中的数据,不存储数据,数据在表中. ---一个由查询语句定义的虚拟表. ---查询语句创建表 create table emp a ...
- luogu P2731 骑马修栅栏 Riding the Fences
入度为奇数的点,搜他. 最好邻接矩阵... #include<cstdio> #include<iostream> #define R register int using n ...
- Hive_Hive的数据模型_外部表
Hive的数据模型之外部表 外部表(External Table)- 指向已经在HDFS中存在的数据,可以创建Partition- 它和内部表在元数据的组织上是相同的,而实际数据的存储则有较大的差异. ...
- NET Core容器
NET Core容器化之多容器应用部署@Docker-Compose 1.引言 紧接上篇.NET Core容器化@Docker,这一节我们先来介绍如何使用Nginx来完成.NET Core应用的反 ...
- FusionCharts图表控件中文版使用手册
三要素:swf.data.xml.承载图表的载体 1.Swf: 按照你所设计的图表类型加载相应的.swf文件到你的工程即可(eg:若你想生成一张二维柱状图,那么在你的工程里就必须包含Column2D. ...
- PT100/PT1000
热敏电阻:互换性差,非线性严重,测量范围窄-50~300℃. 金属电阻:准备稳定可靠.-200~500℃ PT100:测量范围宽比PT1000宽,分辨率比PT1000低(100倍,即PT1000每变化 ...
- C#微信支付
回归主题,16年1月初我对微信开发比较好奇,由于自己是一个比较喜欢钱的人,所以对支付功能颇为冲动,就用公司信息在微信平台申请了一个服务号,还给腾讯打赏了300大洋做了下认证,抽空看了下微信支付官方的文 ...
- 机器学习框架ML.NET学习笔记【9】自动学习
一.概述 本篇我们首先通过回归算法实现一个葡萄酒品质预测的程序,然后通过AutoML的方法再重新实现,通过对比两种实现方式来学习AutoML的应用. 首先数据集来自于竞赛网站kaggle.com的UC ...
- P3818 小A和uim之大逃离 II
题目背景 话说上回……还是参见 https://www.luogu.org/problem/show?pid=1373 吧 小a和uim再次来到雨林中探险.突然一阵南风吹来,一片乌云从南部天边急涌过来 ...
- Linux环境 Java内存快速查看
最近生产环境遇到内存老是占用很大的情况,16G的内存Free的内存只剩100多M,仿佛一颗定时炸弹一般,说不定就服务Down了.于是开始网上不断的找查看内存使用的方法.现学现卖,以下通过一个例子来演示 ...