c++入门学习⑤——对象模型和this指针

目录

前言:

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

注意:

案例:

this指针的概念

介绍:

用途:

错误案例:

解决方案:

 注意函数为什么用引用返回呢,如果用值返回,结果会产生怎样的变化,why?

空指针访问成员函数

简介:

错误案例:

修改:

 总结:

const修饰成员函数

常函数:

常变量:

当成员函数写入const后

正常的赋值不能进行了,why?

结语:


前言:

这篇博客接着上回有关c++内容讲解有关对象模型和this指针的内容💪

传送门:

c++入门学习①-CSDN博客

c++入门学习②-CSDN博客

c++入门学习③——封装-CSDN博客

c++入门学习④——对象的初始化和清理-CSDN博客

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

成员函数成员变量分开储存
只有非静态的成员变量才属于类的对象,其余都不是类的对象

注意:

空对象所占内存为1👉因为c++编译器,会给每个空对象分配一个空间,每个空对象都应该有一个独一无二的内存地址,为了区分空对象内存的位置,所以内存空间设置为1。

空对象为1,非空对象为类里成员所占用的空间,其中只有非静态成员变量才属于类的对象中。


案例:

#include<iostream>
#include<string>
using namespace std; 
//成员函数和成员变量分开储存
// 只有非静态的成员变量才属于类的对象

class person {
public:
    int m_a;//非静态,属于类的对象上
    static int m_b;
    void func() {//非静态成员函数,不属于类的对象

    }
    static void test() {//静态成员函数,只有一份,不属于类的对象上

    }
};
int person::m_b = 0;
void test1() //测试案例
{ 
    person p;
    cout << sizeof(p) << endl;
    //空对象所占内存为1
    //👉因为c++编译器,会给每个空对象分配一个空间,为了区分空对象内存的位置
    //每个空对象都应该有一个独一无二的内存地址
    //有一个int成员,则对象所占空间为4
    //👉空对象为1,非空对象为类里属性成员所占用的空间
    //添加一个静态成员后发现所占内存空间仍是4,没改变
    //再添加一个非静态成员函数,内存还没变,仍为4,不属于类的对象
    //再加一个静态成员函数,内存仍为4,静态成员变量不属于类的对象上。
}

int main()
{
    test1();
    system("pause");
    return 0;
}

this指针的概念

介绍:

成员变量和成员函数是分开存储
this指针指向被调用的成员函数所属对象
它是隐含在每一个非静态成员函数的一种指针,不须定义

用途:

1.当形参和成员变量同名时,可用this指针区分
2.返回对象本身,用*this

错误案例:

#include<iostream>
#include<string>
using namespace std; 
//成员变量和成员函数是分开存储的
//this指针指向被调用的成员函数所属对象
//隐含在每一个非静态成员函数的一种指针,不须定义
//用途:当形参和成员变量同名时,可用this指针区分
//返回对象本身,用*this

class person {
public:
    person(int age) {//构造函数初始化对象
        age = age;
   }
    int age;
};

void test1() //测试案例
{ 
    person p1(12);
    cout << "p1年龄" << p1.age << endl;//输出一个长串数字,其实实际上age未真正赋值
}

int main()
{
    test1();
    system("pause");
    return 0;
}

解决方案:

1.把int age改为int m_age; 

2.加一个this

示例:

class person {
public:
    person(int age) {//构造函数初始化对象
        this->age = age;
/*this指针指向被调用成员函数所属对象,下面person p1(12)是调用的函数,
这个函数是p1在调用,this指向p1。
*/
   }
    int age;
};

用*this 返回对象示例:

#include<iostream>
#include<string>
using namespace std; 
//成员变量和成员函数是分开存储的
//this指针指向被调用的成员函数所属对象
//隐含在每一个非静态成员函数的一种指针,不须定义
//用途:当形参和成员变量同名时,可用this指针区分
//返回对象本身,用*this

class person {
public:
    person(int age) {//构造函数初始化对象
        this->age = age;
   }
    person& personaddage(person& p) {
        this->age += p.age;//所调用这个函数的对象的年龄加上所输入的年龄=所调用这个函数的对象的年龄
        return *this;
    }//返回本体,用引用的方式返回
    int age;
};

void test1() //测试案例
{ 
    person p1(10);
    person p2(10);
    p2.personaddage(p1);//p2调用函数personaddage,结果为20
    //执行完函数如果返回调用函数的对象,则可以实现无限增加年龄
    p2.personaddage(p1).personaddage(p1).personaddage(p1);
    cout << p2.age << endl;//结果为40
}

int main()
{
    test1();
    system("pause");
    return 0;
}

 注意函数为什么用引用返回呢,如果用值返回,结果会产生怎样的变化,why?

返回值则结果为20👉
返回值则按照对象自身拷贝构造一个新的数据,构造返回值,每一次都是一个新对象

引用会返回这个原本的对象而不会和返回值一样创建一个新的对象。

空指针访问成员函数

简介:

空指针可以调用成员函数,但由于有this指针,容易有坑,出错。

错误案例:

#include<iostream>
#include<string>
using namespace std; 
//空指针可以调用成员函数,但由于有this指针,容易有坑

class person {
public:
    void classname() {
        cout << "this is person class" << endl;
   }
    void personage() {
        cout << "age=" <<m_age<< endl;//存在类属性,其实在属性的前面默认都会加上一个this->,空指针调用这个函数,导致this没有指向一个确切的值
    }
    int m_age;
};

void test1() 
{ 
    person* p=NULL;
    p->classname();//只有这一个函数时,程序不崩
    p->personage();//这个函数出错,程序崩溃了,报错原因是传入指针为空
    //如何解决呢?
}

int main()
{
    test1();
    system("pause");
    return 0;//代码崩了
}

修改:

 void personage() {
     if (this == NULL) {
         return;
     }
     cout << "age=" <<m_age<< endl;//存在类属性,其实在属性的前面默认都会加上一个this->,空指针调用导致this没有指向一个确切的值
 }
 int m_age;

 总结:

提高代码的健壮性用if来预防有空指针的调用,空指针可以访问,但是不可以去使用在正常的带属性的一个成员函数内,会导致程序崩溃的

const修饰成员函数

用const修饰成员函数则成员函授叫做:常函数

用const修饰成员变量则成员变量叫做:常变量

常函数:

1.成员函数括号后加上const,修饰对象为this指针

2.常函数不可以修改成员属性

3.如果要修改成员属性,成员属性前必须要加上关键字mutable

常变量:

1.声明对象前加上const则称为常对象

2.常对象只能调用常函数,因为普通函数可以修改成员属性,而常函数不可以修改一般成员属性,因此常对象不可调用常函数。

当成员函数写入const后

正常的赋值不能进行了,why?

每一个成员函数都有一个this指针,this指针本质是指针常量,指针指向不可修改,

#include<iostream>
#include<string>
using namespace std; 
//常函数和常对象👉const修饰后这样叫成员函数和对象
//常对象只能调用常函数.常对象不能修改

class person {
public:
    void showperson() const //在成员函数后加const,修饰的是this指向,
    {
       m_b = 100;
    }
    void func() {
        m_a = 100;
    }
    int m_a;
    mutable int m_b;//特殊变量,即使是在常函数中也可以修改这个值的大小
};

void test1() 
{ 
    const person p;
    //p.m_a = 100;错误
    p.m_b = 100;//正确,因为这里m_b是一个特殊的变量,可以修改,在常对象下可以修改。
    //p.func();不允许,不正确,常对象不可以调用普通函数,因为普通函数可以修改属性,而常对象要求不能修改属性
}

int main()
{
    test1();
    system("pause");
    return 0;

结语:

希望这篇有关c++对象模型和this指针的博客对大家有所帮助,欢迎大佬们留言o(* ̄▽ ̄*)ブ

一起学习进步!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值