博客
关于我
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/

    你可能感兴趣的文章
    opencv30-图像矩
    查看>>
    opencv32-基于距离变换和分水岭的图像分割
    查看>>
    opencv4-图像操作
    查看>>
    opencv5-图像混合
    查看>>
    opencv6-调整图像亮度和对比度
    查看>>
    opencv7-绘制形状和文字
    查看>>
    opencv8-图像模糊
    查看>>
    opencv9-膨胀和腐蚀
    查看>>
    OpenCV_ cv2.imshow()
    查看>>
    opencv_core.dir/objects.a(vs_version.rc.obj)‘ is incompatible with i386:x86-64 output
    查看>>
    opencv——图像缩放1(resize)
    查看>>
    opencv——最简单的视频读取
    查看>>
    Opencv——模块介绍
    查看>>
    OpenCV与AI深度学习 | 2024年AI初学者需要掌握的热门技能有哪些?
    查看>>
    OpenCV与AI深度学习 | CIB-SE-YOLOv8: 优化的YOLOv8, 用于施工现场的安全设备实时检测 !
    查看>>
    OpenCV与AI深度学习 | CoTracker3:用于卓越点跟踪的最新 AI 模型
    查看>>
    OpenCV与AI深度学习 | OpenCV中八种不同的目标追踪算法
    查看>>
    OpenCV与AI深度学习 | OpenCV图像拼接--Stitching detailed使用与参数介绍
    查看>>
    OpenCV与AI深度学习 | OpenCV如何读取仪表中的指针刻度
    查看>>
    OpenCV与AI深度学习 | OpenCV常用图像拼接方法(一) :直接拼接
    查看>>