博客
关于我
C++类和对象的学习【part3:对象特性2.0】
阅读量:393 次
发布时间:2019-03-05

本文共 4131 字,大约阅读时间需要 13 分钟。

C++类和对象学习【part3:对象特性】

成员变量和成员函数的存储

在C++中,类内的成员变量和成员函数分开存储。只有非静态成员变量才属于类的对象上。类中的成员可以分为以下几种:

  • 非静态成员变量:占用对象空间
  • 静态成员变量:不占用对象空间
  • 非静态成员函数:不占用对象空间
  • 静态成员函数:也不占用对象空间

例如,以下代码展示了类Person的不同成员:

class Person {public:    Person() {        mA = 0;    }    int mA; // 非静态成员变量,占用对象空间    static int mB; // 静态成员变量,不占用对象空间    void func() {        cout << "mA:" << this->mA << endl;    }    static void sfunc() {    }};

需要注意的是:一个空的类内存占用一个字节,目的是区分不同的空对象占用的内存位置。如果类中含有非静态成员变量,则占用该成员变量字节数,若有多个则累加。


this指针概念

this指针是C++中每一个非静态成员函数内隐含的一种指针,它指向被调用的成员函数所属的对象。

this指针的用途

  • 当形参和成员变量同名时,可以用this指针来区分。
  • 在类的非静态成员函数中返回对象本身,可以使用return *this
  • 例如:

    Person& PersonAddPerson(Person p) {    this->age += p.age;    return *this;}

    调用时可采用递归式调用:

    p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);

    空指针访问成员函数

    我们可以定义一个类的指针,但令其为空。空指针可以调用成员函数,但需注意以下几点:

  • 空指针调用成员函数时,不能使用this指针。
  • 如果成员函数中用到了this指针,则不能使用空指针。
  • 例如:

    class Person {public:    void ShowClassName() {        cout << "我是Person类!" << endl;    }    void ShowPerson() {        if (this == NULL) {            return;        }        cout << mAge << endl;    }public:    int mAge;};void test01() {    Person * p = NULL;    p->ShowClassName(); // 空指针可以调用成员函数    p->ShowPerson(); // 如果成员函数中用了this,则不可以}

    需要关注的点:

    • 空指针的定义方式。
    • 空指针调用成员函数的方式。
    • 使用成员变量时,不能用空指针。
    • 如果出现上述情况,应当用判断语句增加程序健壮性。

    const修饰成员函数

    常函数

    成员函数后加const后,我们称为这个函数为常函数。常函数内不可以修改成员属性,但如果成员属性声明时加mutable修饰,则在常函数中依然可以修改。

    常对象

    声明对象前加const,则称该对象为常对象。常对象只能调用常函数。

    例如:

    class Person {public:    Person() {        m_A = 0;        m_B = 0;    }    void ShowPerson() const {        // const Type* const pointer;        // this = NULL; // 不能修改指针的指向        // this->mA = 100; // 但是this指针指向的对象的数据是可以修改的        // const修饰成员函数,表示指针指向的内存空间的数据不能修改,除了mutable修饰的变量        this->m_B = 100;    }public:    int m_A;    mutable int m_B; // 可修改,可变的};

    常对象的定义方式:

    const Person person; // 常对象cout << person.m_A << endl; // 常对象不能修改成员变量的值,但可以访问person.m_B = 100; // 但是常对象可以修改mutable修饰的成员变量person.MyFunc(); // 常对象只能调用const的函数

    全局函数作友元

    友元关键字为friend。友元的种类包括全局函数作友元、类作友元和成员函数作友元。

    全局函数作友元

    对于全局函数作友元,代码如下:

    class Building {public:    friend void goodGay(Building *building); // 声明全局函数goodGay是Building类的好朋友public:    Building() {        this->m_SittingRoom = "客厅";        this->m_BedRoom = "卧室";    }public:    string m_SittingRoom; // 客厅private:    string m_BedRoom; // 卧室};void goodGay(Building *building) {    cout << "好基友正在访问: " << building->m_SittingRoom << endl;    cout << "好基友正在访问: " << building->m_BedRoom << endl;}void test01() {    Building b;    goodGay(&b); // 传入对象的地址}

    需要注意的是:全局函数作为友元时,需要在类中声明friend,并接受类的指针或对象作为参数。


    类作友元

    类作友元的实现方式如下:

    class Building;class goodGay {public:    goodGay();    void visit();private:    Building *building;};class Building {public:    friend class goodGay; // 声明goodGay类是Building类的好朋友public:    Building();public:    string m_SittingRoom; // 客厅private:    string m_BedRoom; // 卧室};Building::Building() {    m_LivingRoom = "客厅";    m_BedRoom = "卧室";}goodGay::goodGay() {    building = new Building; // 在堆区创建Building对象,并用指针building维护!}void goodGay::visit() {    cout << "好基友正在访问" << building->m_SittingRoom << endl;    cout << "好基友正在访问" << building->m_BedRoom << endl;}void test01() {    goodGay gg;    gg.visit();}

    需要注意的是:类作友元需要在声明时明确标注friend,且友元类可以访问原类的私有成员。


    成员函数作友元

    成员函数作友元的实现方式如下:

    class Building;class GoodGay {public:    GoodGay();    void visit();    void visit2();private:    Building *building;};class Building {public:    friend void GoodGay::visit(); // 声明GoodGay类下的visit成员函数作为Building类的好朋友public:    Building();public:    string m_LivingRoom; // 客厅private:    string m_BedRoom; // 卧室};Building::Building() {    m_LivingRoom = "客厅";    m_BedRoom = "卧室";}GoodGay::GoodGay() {    building = new Building; // 在堆区创建Building对象,并用指针building维护!}void GoodGay::visit() {    cout << "visit 正在访问" << building->m_LivingRoom << endl;    cout << "visit 正在访问" << building->m_BedRoom << endl;}void GoodGay::visit2() {    cout << "visit2 正在访问: " << building->m_LivingRoom << endl;    // cout << "visit 正在访问" << building->m_BedRoom << endl; // 不可以访问}void test01() {    GoodGay gg;    gg.visit();    gg.visit2();}

    需要注意的是:成员函数作友元需要在目标类中声明具体的成员函数作为友元。


    通过以上内容,可以更好地理解C++中类和对象的特性,以及如何在实际编程中灵活使用这些特性。

    转载地址:http://upewz.baihongyu.com/

    你可能感兴趣的文章
    NumPy 或 Pandas:将数组类型保持为整数,同时具有 NaN 值
    查看>>
    numpy 用法
    查看>>
    Numpy如何使用np.umprod重写range函数中i的python
    查看>>
    oauth2-shiro 添加 redis 实现版本
    查看>>
    OAuth2.0_JWT令牌-生成令牌和校验令牌_Spring Security OAuth2.0认证授权---springcloud工作笔记148
    查看>>
    OAuth2.0_JWT令牌介绍_Spring Security OAuth2.0认证授权---springcloud工作笔记147
    查看>>
    OAuth2.0_介绍_Spring Security OAuth2.0认证授权---springcloud工作笔记137
    查看>>
    OAuth2.0_完善环境配置_把资源微服务客户端信息_授权码存入到数据库_Spring Security OAuth2.0认证授权---springcloud工作笔记149
    查看>>
    OAuth2.0_授权服务配置_Spring Security OAuth2.0认证授权---springcloud工作笔记140
    查看>>
    OAuth2.0_授权服务配置_令牌服务和令牌端点配置_Spring Security OAuth2.0认证授权---springcloud工作笔记143
    查看>>
    OAuth2.0_授权服务配置_客户端详情配置_Spring Security OAuth2.0认证授权---springcloud工作笔记142
    查看>>
    OAuth2.0_授权服务配置_密码模式及其他模式_Spring Security OAuth2.0认证授权---springcloud工作笔记145
    查看>>
    OAuth2.0_授权服务配置_资源服务测试_Spring Security OAuth2.0认证授权---springcloud工作笔记146
    查看>>
    OAuth2.0_环境介绍_授权服务和资源服务_Spring Security OAuth2.0认证授权---springcloud工作笔记138
    查看>>
    OAuth2.0_环境搭建_Spring Security OAuth2.0认证授权---springcloud工作笔记139
    查看>>
    oauth2.0协议介绍,核心概念和角色,工作流程,概念和用途
    查看>>
    OAuth2授权码模式详细流程(一)——站在OAuth2设计者的角度来理解code
    查看>>
    OAuth2:项目演示-模拟微信授权登录京东
    查看>>
    OA系统多少钱?OA办公系统中的价格选型
    查看>>
    OA系统选型:选择好的工作流引擎
    查看>>