C++语法系列 类和对象Ⅱ

C++对象模型

成员变量和成员函数分开存储

只有普通成员变量才属于对象,函数和静态成员变量都不属于对象

class Person{
public:
    int a;
    int b;
    char c;

    void prt() {
        cout << a << endl << b << c;
    }
};

class VD{

};

void test() {
    Person p;
    VD v;
    cout << sizeof p << endl;		//12,内存对齐,4 + 4 + 4,而函数不占空间
    cout << sizeof v << endl;		//1
    //编译器会为空对象分配一个占位的1字节空间
}
this指针

既然多个对象会共享一个成员函数,即成员函数只在内存中存储一份,那么这个成员函数怎么区分是哪个对象调用的自己呢?

通过this指针

this指针指向被调用的成员函数所属的对象,即谁调用函数,this就指向谁

this指针隐含在每一个非静态成员函数内

  • 本质

this指针的本质是指针常量,不可以改变指向

  • 其他用途
    • 当形参和成员变量重名时,可以用this来区分(和Java一样)this->age = age;
    • 在类的非静态成员函数中返回对象本身时,可使用return *this;
空指针调用成员函数

空指针可以调用成员函数,条件是此函数内没有用到this指针

class Person{
public:
    int age;

    Person() {
        age = 10;
    }

    void showClassName() {
        cout << "Class:Person";
    }

    void showAge() {
        // if (!this) return;	//这行代码可以提高程序的健壮性
        cout << age;		//编译器会改为cout << this->age; 用到了this指针
    }
};

void test() {
    Person* p = nullptr;
    p->showClassName();		//可以运行
    p->showAge();			//程序会崩
}
const修饰成员函数、成员变量
常函数
  • 成员函数后加const我们称这个函数为常函数
  • 常函数内不可以修改成员属性
  • 成员属性声明时加关键字mutable后,在常函数中可修改
class Person{
    public:
    int age;
    mutable int b;			//b可以改
    void func() const {		//常函数,事实上,const修饰的是this指针
        //age = 100;			//不可修改,报错
        b = 200;			//正确
    }
};
常对象
  • 声明对象前加const称该对象为常对象
  • 常对象的属性不可修改,除非该属性用mutable修饰
  • 常对象只能调用常函数,防止通过普通函数间接的修改普通属性
void test() {
    const Person p1;
    p1.age = 100;		//错误
    p1.b = 200;			//正确
}
友元

在程序里,有些私有属性也想让类外的一些特殊函数或类进行访问,这就需要用到友元的技术

友元的目的就是让一个函数或者类访问另一个类中的私有成员

关键字 friend
三种实现
  • 类做友元
class House;
class GoodGay{
public:
    GoodGay();		//类外实现
    void visit();	//类外实现
    House* house;	//构造函数内必须初始化此指针
};

class House {
    friend class GoodGay;   //GoodGay是本类的好朋友,可以访问本类的私有成员bedroom
private:
    string bedroom;
public:
    string livingRoom;
    House();		//类外实现
};

House::House() {        //类外实现构造函数
    livingRoom = "客厅";
    bedroom = "卧室";
}

GoodGay::GoodGay() {    //类外实现构造函数
    house = new House;
}

void GoodGay::visit() { //类外实现成员函数
    cout << "好基友正在访问:" << house->livingRoom << endl;
    cout << "好基友正在访问:" << house->bedroom << endl;
}

void test() {
    GoodGay goodGay;
    goodGay.visit();
}
  • 全局函数做友元
class House {
    friend void myHouse();      	//这个全局函数是本类的好朋友,所以可以访问本类的私有成员
    //friend void GoodGay::visit();	//GoodGay类下的visit成员函数是本类的好朋友,成员函数做友元
private:
    string bedroom;
public:
    string livingRoom;
    House() {
        livingRoom = "客厅";
        bedroom = "卧室";
    }
};

void myHouse() {
    House house;
    cout << "好基友正在访问:" << house.livingRoom << endl;
    cout << "好基友正在访问:" << house.bedroom << endl;
}
  • 成员函数做友元

见上方

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大西洋码头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值