目录
前言:
成员变量和成员函数分开储存
⭐
注意:
案例:
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指针区分
//返回对象本身,用*thisclass 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指针区分
//返回对象本身,用*thisclass 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(* ̄▽ ̄*)ブ
一起学习进步!!!