C++中的类

一、接口

1.举个例子,A想要去B的家里做客,当然,A不能直接穿墙或瞬移进入到B家里去访问,他必须通过某种方式或渠道才能进入到B的家里。这时候,这种方式或渠道可以称之为B的家对外的接口。
2.接口可以分为两种:公共接口(Public) 和 私有接口(private) 。公共接口可以看做是B家的窗户、大门,任何人都可以访问;私有接口则可以看做B家里的私密通道,只有他家里的成员对象或者通过他家里的私密方法才能进入和访问。

请看如下代码:

#ifndef Stock_hpp
#define Stock_hpp

#include <iostream>
#include <stdio.h>
#include <string.h>

/*
 *class关键字指出这些代码定义了一个类设计
 *Stock是这个类的类型名(类的名称)
 *通过这个声明,我们可以创建Stock类型的变量(也可以说是Stock的对象)
 **/
class Stock
{
private:

    std::string company;
    double share_value;
    double total_value;
    long share;
    void set_tot(){total_value = share *share_value;};

public:

    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();

};

#endif /* Stock_hpp */

简要说明:

1.class关键字指出这些代码的作用:定义了一个类设计
2.Stock是这个类的类型名(也可以理解为类名;
3.通过这个声明,我们可以创建Stock类型的变量(也可以说是Stock类型的对象)
4.private和public则分别是接口中的私有部分和公有部分

1.访问控制

关键字private和public对类成员的访问控制,我们可以通过类的对象来访问公有部分,但是访问私有成员则只能通过公有成员函数。比如,我们想修改Stock类的total_value成员,只能通过Stock的成员函数。因此公有成员函数是程序 和 对象的私有成员之间的桥梁,提供了对象和成员之间的接口。防止程序直接访问数据被称为数据隐藏 。C++还提供了第三个访问控制关键字protected类的成员可以是数据类型,也可以是函数。

2.控制对成员的访问:公有还是私有

无论类成员是数据成员还是成员函数,我们都可以在类的公有部分或者是私有部分中声明它。由于隐藏数据是OOP主要目标之一,因此数据项通常放在私有部分,组成类接口的成员函数放在公有部分。如上面的代码,我们可以把成员函数放在私有部分中,此时我们不能直接通过程序调用这些函数,但是我们可以通过公有部分中的成员函数来访问它们。

在C++中,类与结构体具有相同的特性,它们之间的唯一区别就是:结构体默认访问类型是public公有部分,类默认访问的是private私有部分。我们通常使用类来实现类描述,而结构体通常只用来表示纯粹的数据对象。

二、实现类成员函数

我们在类声明中声明成员函数的函数原型之后,还需要实现对应的函数。成员函数的定义与常规函数的定义非常相似,他们也有函数头和函数体,也有返回类型和参数。但是他们还有两个特殊的标识特征:

1.定义成员函数时,使用作用域解析运算符(::)来标识函数所属的类
2.类方法可以访问类的private组件。

如下:
void Stock :: update(double price)

1.我们定义的update( )函数是Stock类成员
2.此外,我们还可以在其它的类中也定义一个名为update( )的成员函数,例如,People( )类中的update( )函数的函数头为:
void People :: update(double peice);

也就是说,作用域解析运算符确定了方法(函数)定义对应的类的身份,函数update( )具有类作用域(class scope)Stock类的其它成员不必再使用作用域解析运算符就可以使用update( )方法,这是因为他们属于同一个类,update( )是可见的
类方法的完整名称中包括类名,Stock :: update( )是函数的限定名(qualified name);而update( )是全名的缩写,是非限定名(unqualified name ),它只能在类作用域中使用。
请看如下代码:

#include "Stock.hpp"
#include <iostream>
using namespace std;

#pragma mark --
/**函数void acquire(const std::string & co ,long n, double pr);的实现**/
void Stock::acquire(const std::string &co, long n, double pr)
{
    company =  co;
    if (n > 0)
    {
        cout << "Number of shares can’t ne negative;"
             << company
             << "Share set to Zero."
             << endl;
        share = 0;
    }
    else
    {
        share = n;
    }
    share_value = pr;
    set_tot();
}

#pragma mark --
/**函数void Stock::buy(long num, double price)的实现**/
void Stock::buy(long num, double price)
{
    if (num < 0) {
        cout << "Number of shares purchase can't be negative."
             << "Transaction is aborted ;"
             << endl;
    }
    else
    {
        share += num;
        share_value = price;
        set_tot();
    }
}

void Stock:: sell(long num, double price)
{
    if (num < 0)
    {
        cout << "Number of shares sold can't be negative."
             << "Tansaction is aborted."
             << endl;
    }
    else if(num >share)
    {
        cout << "You can't sell more than you have!"
             << "Transaction is aborted ."
             << endl;
    }
    else
    {
        share_value = price;
        set_tot();
    }
}

void Stock:: update(double price)
{
    share_value = price;
    set_tot();
}

void Stock::show()
{
    cout << "Company:" << company
         << "Shares :" << share
         << endl
         << "Share Price: $" << share_value
         << "Total Worth: $" << total_value
         << endl;

}
1.成员函数说明:

4个成员函数设置或者重新设置了total_value成员值,这个类并非将计算部分的代码编写了四次,而是让每个使用到的函数都去调用set_out( )函数。set_out( )只是实现代码的一种方式,不是公有接口的组成部分,所以在这个类中将它声明为私有成员函数(即:编写这个类的人可以使用,但编写代码使用这个类的人不能使用)。这种方式的好处在于通过函数调用,提高代码的重用率,同时在修改起来也比较容易。

2.内联函数

定义位于类声明中的函数都将自动成为内联函数,因此,如上代码,Stock :: set_tot()是一个内联函数。
类声明常将短小的成员函数作为内联函数,set_tot()符合要求。
此外,也可以在类声明之外定义成员函数,并将其成为内联函数。只需要在类实现部分中定义函数时使用inline限定符即可。
如下:

class Stock
{
private:
    ...
    void set_tot();
public:
    ...
    ...
};

inline void Stock::set_tot()
{
    total_value = share *share_value;
}

内联函数的特殊规则要求在每个使用他们的文件中都对其进行定义,确保内联定义对多文件程序中的所有文件都是可用的。。最简单的方法就是:将内联定义放在定义类的头文件中
根据改写规则:在类声明中定义方法等同于用原型替换方法定义,然后在类声明的后面讲定义改写为内联函数

3.方法使用哪个对象?

如下代码:

    Stock kate,joe;//创建两个Stock对象
    kate.show();//1.
    joe.show();//2.

第一条语句调用kate对象的show()成员,这意味着show()shares解释为 kate.shares,将share_value解释为kate.shares。同理,第二条也如此。
注意:

调用成员函数时,它将使用被用来调用它的对象的数据成员

4.使用类
#include <iostream>

#include "Stock.hpp"

using namespace std;
int main(int argc, const char * argv[]) {

    Stock class_obj;

    class_obj.acquire("GuPiao007", 20, 12.12);
    class_obj.show();

    class_obj.buy(10, 18.88);
    class_obj.show();

    class_obj.sell(400, 20.11);
    class_obj.show();

    class_obj.buy(8888, 40.123);
    class_obj.show();

    class_obj.sell(3000000, 0.111);
    class_obj.show();

    return 0;
}

输出结果:

Number of shares can’t negative;GuPiao007
Share set to Zero.
Company:GuPiao007Shares :0
Share Price: $12.12Total Worth: $0
Company:GuPiao007Shares :10
Share Price: $18.88Total Worth: $188.8
You can't sell more than you have!Transaction is aborted .
Company:GuPiao007Shares :10
Share Price: $18.88Total Worth: $188.8
Company:GuPiao007Shares :8898
Share Price: $40.123Total Worth: $357014
You can't sell more than you have!Transaction is aborted .
Company:GuPiao007Shares :8898
Share Price: $40.123Total Worth: $357014
Program ended with exit code: 0

在前面,我们定义和实现了成员函数之后,就会使用到这个类。比如,我们在main.cpp类中使用Stock类中公有部分的成员函数时,就需要先导入Stock类的头文件 。之前,我们在使用cincout方法时,就导入了它们所在类的头文件iostream。如下:

#include <iostream>
#include "Stock.hpp"

当然,你会发现它们两个有所区别,一个使用< >来包括头文件名,一个使用" "来包括头文件名。它们的区别就是:前者用于导入系统所有类的头文件,而后者用于导入程序员自己创建类的头文件

说明:

1.在上面的代码中,class_obj是通过Stock类的类名创建的Stock类的对象。用一个例子来说明类与对象的关系,就是:类就好比是永辉超市集团,而对象就是我们所见到的永辉超市。当然,这个例子比喻得比不是十分恰当。
2.我们在使用Stock类并编译时,一定要确保使用它的类和Stock.cpp一起编译,并确保Stock.hpp在当前文件夹内。

5.总结
提供类声明

1.指定类设计的第一步是提供类声明,类声明和结构声明类似可以包括数据成员和结构成员。
2.声明通常分为两部分:私有部分公有部分。私有部分中声明的成员只能通过成员函数进行访问;声明在公有部分中的成员可以被使用类对象的程序直接访问。
3.一般类声明的格式如下:

class className {
private:
data member declarations
public:
member function prototypes
};

4.公有部分的内容构成了设计的抽象部分:```公有接口```。将数据封装到私有部分中可以保护数据的完整性,这被称为```数据隐藏```。
实现类成员函数

指定类设计的第二步是实现类成员函数。可以在类声明中提供完整的函数定义,而不是函数原型。但是通常的做法就是单独提供函数定义(除非函数非常小)。在这种情况下,我们需要使用作用域解析运算符来指出成员函数属于哪个类。看个例子:LOL类有个doubleKill()成员函数,这个成员函数返回int类型数据,则该成员函数的函数头如为:int LOL::doubleKill()

创建类的对象

创建一个类的对象,就是将该类进行实例化。具体的创建方法为:className classObj;,类对象通过成员运算符句点来调用类的成员函数,比如:

className classObj;
classObj.memberFunc();

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • C++文件 例:从文件income. in中读入收入直到文件结束,并将收入和税金输出到文件tax. out。 检查...
    SeanC52111阅读 2,751评论 0 3
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,500评论 1 51
  • 前言 本系列文章介绍的并不是一些艰深的内容。重要的是找到一些以前学习过程中主动地、被动地错误吸收的知识将它从脑中剔...
    柳豪阅读 1,464评论 0 51
  • 类的默认访问标识符是 internal,成员的默认访问标识符是 private 1.类的 构造函数 是类的一个特殊...
    小羊快跑阅读 272评论 0 1
  • 琵琶弹断了我的弦 猫看惯了我的帽子 我从西班牙的滨海之北出发 从沉美的萨克斯吹出 咸咸的海风 还有大胡子的烟草味 ...
    神农百草阅读 193评论 0 0