C++学习:类

news2024/11/8 10:56:04

一、类的概念

类是一种将抽象转换为用户定义类型的C++工具,它将数据和数据处理组合成一个整体。

比如股票类,首先要考虑如何表示股票。可以将某人持有的股票当成一个基本单元,数据包括他持有股票的数量,哪个公司的股票,还有最初购买的价格和购买的时间,股票的处理有增持,卖出,更新价格等。

类一般由类声明和类方法定义两部分组成,

类声明:以数据成员的方式描述部分,以成员函数的方式描述公有接口;

类方法定义:描述如何实现类成员函数。

可以这么说,类声明就是画个饼,类方法就是去实现这个饼。

二、类的声明

一般将类声明放在头文件中,就是.h文件,将类的实现放在源文件中,就是.cpp文件。

下面是stock类的类声明

#ifndef STOCK_H
#define STOCK_H
#include <string>

using namespace std;

class stock
{
private:
    string company; //股票发行的公司
    long shares; //持有股票数量
    double share_val; //每股的价格
    double total_val; //持股的总金额
    void set_tot() {total_val = shares * share_val;}
    
public:
    void acquire(const string& co, long n, double pr);
    void buy(long num, double price);
    void sell(long num, double price);
    void update(double price);
    void show();
};

#endif // STOCK_H

stock是这个类的类型名,我们可以声明stock类型的变量,也称为对象或实例,每个对象都表示一支股票,可以通过下面的声明创建两个stock对象

stock wang; 
stock li; 

 private和public关键字是C++中新出现的,它们用来描述对类成员的访问权限。private表示类的私有部分,public表示类的公有部分。使用类对象的程序可以直接访问类的公有部分;但类的私有部分只能通过类的成员函数来访问。

三、实现类的成员函数

类成员函数的定义与常规函数的定义非常类似,有函数头、函数体,也可以有返回类型和参数。区别在于,定义类的成员函数需要使用类的作用域解析运算符::来标示函数所属的类,类的成员函数可以访问类的私有成员数据。

void stock::update(double price)

 这表示update()函数是stock类的成员函数。

类的成员函数,也就是类的实现代码如下

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

using namespace std;

//acquire()函数管理对某个公司股票首次购买,公司名称,购买数量,每股单价
void stock::acquire(const string& co, long n, double pr)
{
    company = co;
    if(n<0)
    {
        cout << "number of shares can't be nagative; ";
        cout << company << " shares set to 0.\n";
        shares = 0;
    }
    else
    {
        shares = n;
    }
    
    share_val = pr;
    set_tot();
}

//增持股票,增持的数量,和当时的价格
void stock::buy(long num, double price)
{
    if(num < 0)
    {
        cout << "number of shares purchased can't be nagative; ";
        cout <<  " Transaction is aborted.\n";
    }
    else
    {
        shares += num;
        share_val = price;
        set_tot();
    }
}


//减持股票,减持的数量,和当时的价格
void stock::sell(long num, double price)
{
     if(num < 0)
     {
         cout << "number of shares sold can't be nagative; ";
         cout <<  " Transaction is aborted.\n";
     }
     else if(num > shares)
     {
         cout << "you can't sell more than you have! transaction is aborted.\n";
     }
     else
     {
         shares -= num;
         share_val = price;
         set_tot();
     }
}

//更新股票的价格
void stock::update(double price)
{
    share_val = price;
    set_tot();
}


//显示股票的信息
void stock::show()
{
    cout << "Company: " << company << " Shares: " << shares << endl;
    cout << "Share price: " << share_val << " Total Worth: " << total_val << endl;
}

 公有属性的函数没什么好说的,看代码和注释就看的明白。里面有个特别一点的函数set_tot()函数,是计算股票总资产的,这个函数是类的私有成员函数,代码中每个公有成员函数都有使用它,方法都是一样的,就没必要写重复的代码,这样既减少了重复代码,有节省了空间。

三、将类应用于对象

经过头文件和源文件的编写,stock类已经创建好了,可以开始使用了,先创建两个类对象,kate与joe.

stock kate, joe;

 如何使用对象的成员函数

kate.show();
joe.show();

第一句调用kate对象的show()成员函数,这意味着此时的shares代表的是kate.shares,此时的share_val 代表的是kate.share_val 。第二句同理。

所创建的每个新对象都有自己的存储空间,用于存储其内部变量和类成员,但是同一个类的所有对象共享同一组类方法,也就是共用同一套类成员函数。kate和joe都是stock对象,kate.shares占一块内存,joe.shares占另外一块内存,它们是不一样的东西。

四、使用类

C++的目标是让使用类与使用基本的类型尽可能相同。要创建类对象,可以声明类变量,也可以使用new为类对象分配存储空间,可以将对象作为函数的参数和返回值,也可以将一个对象赋值给另一个对象。

下面是类的使用代码示例,创建一个stock对象 dreamer

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

using namespace std;

int main()
{
    stock dreamer;
    dreamer.acquire("hengda", 20, 12.50); //dreamer以每股12.5元的价格买了20股恒大的股票
    dreamer.show();

    dreamer.buy(15, 18.25);//dreamer又以18.25元的价格增持了15股恒大的股票
    dreamer.show();

    dreamer.sell(400,20);//dreamer想以20元的价格卖掉400股,好像在做梦,都没有那么多股票
    dreamer.show();

    dreamer.buy(20000, 20);//dreamer突然有很多钱了,以每股20元的价格,一下子买了20000股恒大的股票
    dreamer.show();

    dreamer.sell(20000, 0.15);//完蛋了,恒大破产了,股票跌到1毛五,赶紧抛吧
    dreamer.show(); //变成穷光蛋了吧


    return 0;
}

输出结果

 

Company: hengda Shares: 20
Share price: 12.5 Total Worth: 250
Company: hengda Shares: 35
Share price: 18.25 Total Worth: 638.75
you can't sell more than you have! transaction is aborted.
Company: hengda Shares: 35
Share price: 18.25 Total Worth: 638.75
Company: hengda Shares: 20035
Share price: 20 Total Worth: 400700
Company: hengda Shares: 35
Share price: 0.15 Total Worth: 5.25

 

六、类的构造函数

其实上面创建的stock类还不完善,还需要为它添加构造函数与析构函数,为什么?

C++的目标是让使用类跟使用基本类型一样简单,但是到目前为止,我们还不能像初始化int变量那样初始化stock对象,也就是说常规的初始化语法不适用于stock类。

如int变量和结构体变量都可以这样初始化

int year = 2023; //int变量初始化

struct thing
{
    char* pn;
    int m;
};

thing amabob = {"wodget", -23};//结构体变量初始化

类对象可不能这么初始化

stock dreamer = {"hengda", 250, 2.5};

 类对象不能这么初始化,是因为数据部分的访问是私有的,这意味着程序不能直接访问数据成员。程序只能通过成员函数来访问数据成员,因此需要设计合适的成员函数,才能将对象初始化,这个合适的函数就是构造函数。

构造函数就是用于构造新对象,将值赋给它们的数据成员。

构造函数没有返回值,构造函数的名字与类名字一样;

还是延续前面的stock类,为其创建一个构造函数,需要为stock对象提供3个值,因此为构造函数提供3个参数,如果指向设置company成员,将其他的值设为0

stock::stock(const string& co, long n, double pr)
{
    company = co;
    
    if(n<0)
    {
        cout << "number of shares can't be nagative; ";
        cout << company << " shares set to 0.\n";
        shares = 0;
    }
    else
    {
        shares = n;
    }

    share_val = pr;
    set_tot();
}

 这个构造函数的代码与acquire()函数的代码相同,区别在于,程序声明对象的时候会自动调用构造函数。这个自动调用也不是那么的自动,还是要做一些工作。可以显式调用也可以隐式调用

显式调用构造函数

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

using namespace std;

int main()
{
    stock dreamer = stock("apple",10, 12); //显式调用构造函数,将dreamer对象初始化

    dreamer.show();

    return 0;
}

 输出结果

Company: apple Shares: 10
Share price: 12 Total Worth: 120

隐式调用构造函数,就是在对象后面直接把参数贴上去

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

using namespace std;

int main()
{
    stock dreamer("apple",10, 12); //隐式调用构造函数,将dreamer对象初始化

    dreamer.show();

    return 0;
}

输出结果是一样的 。

如果程序没有写构造函数,C++的编译器会提供一个默认的构造函数,里面没有初始的数据。

stock::stock() {}

当且仅当程序没有写任何构造函数,编译器才会提供一个默认构造函数,否则,就得自己写一个默认构造函数。

 

定义了常规构造函数和默认构造函数之后,声明一个类对象之后,如果没有调用常规构造函数,程序或自动调用默认构造函数

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

using namespace std;

int main()
{
    stock dreamer; //程序调用默认构造函数

    dreamer.show();

    return 0;
}

 输出结果

Company: no name Shares: 0
Share price: 0 Total Worth: 0

 七、类的析构函数

用构造函数创建对象后,程序负责跟踪该对象,直到过期。对象过期时,程序将自动调用一个特殊的成员函数,这个函数就是析构函数,析构函数完成清理工作,如果构造函数使用new来分配内存,那么析构函数将使用delete释放内存。

西沟函数长这个样子

~stock();

 由于析构函数不用承担任何重要的工作,里面可以不放代码

stock::~stock()
{

}

如果你想看看西沟函数是否运行,可以在析构函数里面放一个打印语句

stock::stock()
{
    cout << "using ~stock().\n"
}

 

七、const成员函数

八、this指针

九、创建对象数组

十、类的作用域

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1114560.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

addEventListener与useeffect相撞的火花

const [a, seta] useState(1) const [loading, setLoading] useState(false) //用于等到某个异步操作返回结果后再允许再次触发fn函数useEffect(() > {document.addEventListener(LazShake.Event.onShakeOnce, () > {fn(listener);});}, []);useEffect(() > {setTim…

Kurento多对多webrtc会议搭建测试

环境ubuntu18.04 KMS版本6.13.0 多对多通信demo7.0.0 KMS运行起来后&#xff0c;通过运行它的一个个demo&#xff0c;来实现不同的功能&#xff0c;它的demo很多如下&#xff1a; https://github.com/Kurento 里面有一对一&#xff0c;多对多&#xff0c;还有一些特效的demo。…

OSI笔记

由7层组成&#xff0c;由下自上分别为&#xff1a; 物理层&#xff08;硬件方面&#xff0c;例如物理网络设备、布线电缆、光纤等&#xff09;&#xff0c; 传输数据主要是比特流0 1 、电信号数据链路层&#xff08;确定了0 1 的分组方式&#xff0c;通过广播的方式&#xff0…

京东商品详情API接口(标题|主图|SKU|价格|库存..)

京东商品详情接口的应用场景有很多&#xff0c;以下为您推荐几种&#xff1a; 电商平台集成&#xff1a;如果想要实现商品查询、购买、支付等功能&#xff0c;提高自身平台的电商能力&#xff0c;可以将京东API接口集成到自己的电商网站或应用程序中。第三方开发者插件&#x…

央国企、金融信创改造必备的Windows AD域控国产替代方案

自国资委下发79号文并明确规定了2027年底前信息系统全面替换的目标后&#xff0c;金融机构、大型央国企均规划起信创改造方案&#xff0c;其中金融机构更是走在8大行业信创前列&#xff0c;成为央国企、医疗、能源等行业国产化改造的参考样板。 在参与并负责某大型金融机构与某…

他海投260万未回本,一天手写200面单到效率提升200%,经历了什么

他们是时代里的“小人物”&#xff0c;正经历着最为蓬勃的商业变革。年轻一代的创业老板们站在十字路口上&#xff0c;比老一辈更懂直播风口、人工智能、云计算、智能制造、数字经济等经济热词的含义。 作为北京快递行业内少见的本地人&#xff0c;范小菲形容自己的创业历程是…

新媒体时代如何做好新型的网络口碑营销?

从人类开始交换商品的时代开始&#xff0c;口碑营销就已经存在&#xff0c;是靠口耳传播的营销方式。小马识途认为进入当今移动互联网时代&#xff0c;口碑营销又有了新的发展&#xff0c;网络口碑营销推广开始普及。营销人员将传统口碑营销与移动互联网营销相结合&#xff0c;…

英语什么时候加s和es

名词变复数一般情况下加s&#xff0c;以s,x,ch,sh结尾加es。一个名词如果表示一个或一样东西&#xff0c;它取单数形式&#xff0c;如果表示两个或更多的这类东西&#xff0c;则需要用名词复数形式。 1 以s,x,sh,ch结尾的词&#xff0c;加es。 2 以辅音字母&#xff08;除a/e/…

(一)库存超卖案例实战——库存超卖现象的产生及其解决方案概述

前言 本节内容我们主要介绍一下web应用中常见的一类问题——产品“超卖”问题&#xff0c;通过一个springboot项目案例完成超卖现象的演示&#xff0c;并针对不同的应用场景下&#xff0c;提供这一类问题的解决方案&#xff0c;关于更详细的解决方案案例实战内容&#xff0c;请…

ATFX汇市:日本9月核心CPI年率降低至2.8%,创出13个月以来新低

ATFX汇市&#xff1a;据日本总务省统计局数据&#xff0c;日本9月核心CPI年率为2.8%&#xff0c;低于前值3.1%&#xff0c;略高于预期值2.7%&#xff0c;创出自2022年9月核心CPI站上3%关口后的新低。今年一月份&#xff0c;日本核心CPI冲高至4.2%&#xff0c;国际金融市场一度猜…

ATA-M4功率放大器都有哪些具体特点及优势

我们的ATA-M系列功率放大器&#xff0c;旨在将它打造为超越ATA-L系列水声功率放大器高频限制的系列产品。其中ATA-M4功率放大器是一款理想的单通道功率放大器。最大输出345Vrms电压&#xff0c;400VA功率&#xff0c;可驱动0~100%的阻性或非阻性负载。输出阻抗匹配多个档位可选…

双11必看,2023京东双11红包首发时间介绍

双11必看&#xff0c;2023京东双11红包首发时间介绍 10月15日星期日消息&#xff1a;在双十一期间姐妹们最关心的就是商品价格、双11红包、跨店满减&#xff0c;因为这3样就决定我们购物成本。据悉&#xff0c;2023年京东双11京享红包首发时间已经确定了10月23日20点。下面小编…

Qemu镜像安全加密测试

文章目录 简介1.已经过时的qemu自带的加密方式介绍1.1.创建secret uuid的xml1.2.产生uuid1.3.给secret赋值1.4.创建一个存储池1.5.在存储池中创建一个镜像1.6.在虚拟机中使用该镜像 2.弃用以上加密方式2.1.原作者Daniel Berrange的观点2.2.Markus Armbruster更深入的操作 3. LU…

精益求精:使用Ansible集中式自动备份核心数据

1、引言 在当今数字化时代&#xff0c;数据是企业和组织的核心资产。为了确保数据的安全性和可恢复性&#xff0c;备份是至关重 要的。然而&#xff0c;手动备份数据可能会繁琐且容易出错&#xff0c;特别是在面对大规模和分布式的数据存储情况下。幸运的是&#xff0c;Ansibl…

2023【建议收藏】uniapp( vue3)使用canvas生成海报并保存,taro/微信小程序也适用

有段时间没写vue了&#xff0c;有点生疏了...... 1、代码有注释&#xff0c;完整代码如下 <template><view class"page"><canvas class"canvas" v-if"isShow" :style"{width:${canvasWidth}px,height:${canvasHeight}px}&…

Python学习笔记——类、魔术方法

食用说明&#xff1a;本笔记适用于有一定编程基础的伙伴们。希望有助于各位&#xff01; 类 类的运用很常见&#xff1a;在大部分情况下&#xff0c;对一些特有的对象&#xff0c;可以使用特定的类来指向它&#xff1a; class Person:name unknownage -1sex 0partner No…

【Proteus仿真】【Arduino单片机】蜂鸣器

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用蜂鸣器等。 主要功能&#xff1a; 系统运行后&#xff0c;蜂鸣器播放音乐。 二、软件设计 /* 作者&#xff1a;嗨小易&#xff08;QQ&#x…

连续/离散的控制系统阶跃测试(包括MATLAB里的step()函数)

阶跃测试 只要是连续时间系统&#xff0c;无论是传递函数还是连续状态空间形式的模型&#xff0c;直接可以用**step()**做阶跃测试&#xff1b;但是对于离散系统而言&#xff0c;不能用step()函数&#xff0c;可以自行编写代码&#xff0c;如下。 1、离散系统&#xff1a;x(k…

PHPEXCEL解决行数超过65536不显示问题

起因自然是导出数据到excel文件时&#xff0c;数据缺少现象。 百度讲解是将xls文件另存为xlsx文件。 除了这里的原因&#xff0c;还有一点是phpExcel存在两个写入类PHPExcel_Writer_Excel2007和PHPExcel_Writer_Excel5&#xff0c;而只有PHPExcel_Writer_Excel2007支持超过65…