❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️麻烦您点个关注,不迷路❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️
目 录
9.11 面向对象的框架模型
9.11.1 成员变量与函数的存储架构
代码举例说明:
9.11.2 this指针
9.11.4 this指针的应用
1. 函数形参与普通成员变量同名,此时可以使用this指针解决
2. this来完成链式操作
9.11.5 const修饰成员函数
点赞👍 + 收藏👐 + 关注👌
9.11 面向对象的框架模型
9.11.1 成员变量与函数的存储架构
C++面向对象最重要的特征之一,就是实现了“封装”、“数据”以及“函数(里面是对数据的操作)”是分别存储的,c++中的非静态数据成员直接内含在类对象中,成员函数虽然内含在class声明之内,却不出现在对象中。 每一个非内联成员函数只会诞生一份函数实例。
此时我们需要考虑一个问题,使用sizeof(Data)计算类的对象所占空间大小是多少?
实际上,我们这个类的大小只有a、和b的大小
char
类型的大小通常是1字节。int
类型的大小通常是4字节。- 静态成员变量不会增加对象的大小,因为它们是类的共享资源。
记住内存对齐原则:对齐是自身类型的整数倍,并且对象的大小包括其成员变量的大小和可能引发的对齐要求所增加的填充字节。
代码举例说明:
结果显示:
源码:
class myClass01{
public:
int num1;
};
class myClass02{
public:
int num1;
static int num2;
};
class myClass03{
public:
void myoutClass(){
cout<<"我是03"<<endl;
}
public:
int num1;
static int num2;
};
class myClass04{
public:
void myoutClass(){
cout<<"我是04"<<endl;
}
static void mycoutclass(){
cout<<"我是04 static"<<endl;
}
public:
int num1;
static int num2;
};
class myClass05{
public:
void myoutClass(){
cout<<"我是04"<<endl;
}
static void mycoutclass(){
cout<<"我是04 static"<<endl;
}
public:
int num1;
char name;
static int num2;
};
void test03(){
myClass01 my_1;
myClass02 my_2;
myClass03 my_3;
myClass04 my_4;
myClass05 my_5;
cout<<"myClass01_my_1 : "<<sizeof (my_1) <<endl;//4
//静态成员变量不在类对象中存储
cout<<"myClass02_my_2 : "<<sizeof (my_2) <<endl;//4
//非静态成员函数不在类对象中
cout<<"myClass03_my_3 : "<<sizeof (my_3) <<endl;//4
//静态成员函数不在类对象中
cout<<"myClass04_my_4 : "<<sizeof (my_4) <<endl;//4
//增加一个char成员变量,变成8字节,内存对齐
cout<<"myClass05_my_5 : "<<sizeof (my_5) <<endl;//8字节
//直接计算类的大小看一下
cout<<"myClass01 : "<<sizeof (myClass01) <<endl;//4
cout<<"myClass02 : "<<sizeof (myClass02) <<endl;//4
cout<<"myClass03 : "<<sizeof (myClass03) <<endl;//4
cout<<"myClass04 : "<<sizeof (myClass04) <<endl;//4
cout<<"myClass05 : "<<sizeof (myClass05) <<endl;//8字节
}
总结:c++类的大小,或者说类创建的对象的存储变量和函数,是分开存储的。只需要计算普通成员变量和普通通成员指针的大小就可以了,但是记住考虑内存对齐。接着我们来继续深入学习this指针.
9.11.2 this指针
根据上面可以知道,成员函数没有存储在对象的内存空间,那C++是如何知道此时对象调用的是哪个对象的成员函数呢?怎么才能知道当前,是不是调用自己的那个成员函数的?
在C++中,成员函数的调用是通过函数指针来实现的,这个函数指针被称为“this指针”,它作为成员函数的隐式参数传递给函数。成员函数通过this指针即可知道操作的是哪个对象的数据。this指针是一种隐含指针,它隐合于每个类的非静态成员数中。this指针无需定义,直接使用即可
当调用一个成员函数时,编译器会在编译时将函数中的this
关键字替换为指向调用对象的指针,并将这个指针传递给函数。因此,成员函数可以访问它所属的对象的所有成员变量和函数,而不需要显式地传递对象的地址或引用。
注意:静态成员函数内部没有this指针,静态成员函数不能操作非静态成员变量
图中所有文字解释都要认真记忆观看,如有所思,必能大成。
9.11.4 this指针的应用
1. 函数形参与普通成员变量同名,此时可以使用this指针解决
2. this来完成链式操作
代码:
class Data4
{
public:
Data4& printData(const char * str){
cout <<str<<" ";
return *this;
}
};
void test05(){
Data4().printData("Jery").printData("Tom").printData("Spike");//链式操作
}
9.11.5 const修饰成员函数
在C++中用const
修饰一个成员函数时,const修饰this指针指向的内存区域,成员函数体内不可以修改本类中的任何普通成员变量,它被称为“常量成员函数”。常量成员函数承诺不会修改对象的状态。
也就是说,在常量成员函数内部,不允许修改成员变量的值(除非该成员变量被声明为mutable
)。
代码:
class Data5{
public:
int a;
int b;
mutable int c;
public:
Data5(int a,int b,int c){
this->a = a;
this->b = b;
this->c = c;
}
void showNum(void) const //增加const只读,不可以修改成员变量
{
//a = 100;//error 直接报错
c = 101;
cout <<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
}
};
void test06(){
Data5 ob1(11,18,36);
ob1.showNum();
}
C++既提供了这样很好的封装性,也提供了不同的方法去破坏这样的封装性,实际上从用户开发角度出发,可以满足大部分场景需求,也能满足多样化实现的步骤。
例如,对于访问private类型私有成员数据的时候。我们只能通过public共有方法去访问私有数据,但是C++还提供了一种可以直接访问private类型的方法------下章节详细介绍一下这个方法(友元函数,祝我们都很有圆子😍😍😍)
点赞👍 + 收藏👐 + 关注👌
❤️您的支持❤️,是博主最大的动力❤️!!互相学习❤️!!共同进步❤️!!一起搞钱❤️!!❤️
⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️十星好评,Erike的专用模板⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️