文章目录
- 1 成员变量和成员函数分开存储
- 2 this指针
- 3 空指针访问成员函数
- 4 const修饰成员函数(常函数与常对象)
- 4.1 常函数
- 4.2 常对象
1 成员变量和成员函数分开存储
C++中,类的成员变量和成员函数分开存储。只有非静态成员变量属于类的对象,占用对象的内存空间。
注1:非静态成员函数和静态成员(包括静态成员变量与静态成员函数)均不属于类的对象,不占用对象的内存空间。
注2:非静态成员函数并非某个对象独有,内存中仅存在一份数据(一份函数实例)。不同对象的某个非静态成员函数共享同一个函数实例,即多个同类型的对象会共用一块代码。
注3:空对象占用内存空间大小为1字节
。每个对象均具有独一无二的内存地址,C++编译器为区分不同的空对象,会为每个空对象分配1个字节的内存空间。
示例:
#include <iostream>
using namespace std;
//空类
class Empty {
};
class Object {
//非静态成员变量:属于类的对象,占用对象的内存空间
int var;
//静态成员变量:不属于类的对象,不占用对象的内存空间
static int s_var;
//非静态成员函数:不属于类的对象,不占用对象的内存空间
void func() {}
//静态成员函数:不属于类的对象,不占用对象的内存空间
static void s_func() {}
};
int main() {
Empty e;
cout << "空对象占用的内存大小:" << sizeof(e) << endl; //1
Object o;
cout << "非空对象占用的内存大小:" << sizeof(o) << endl; //4
return 0;
}
2 this指针
C++提供特殊的对象指针this指针
,用于区分共享的同一块代码(如非静态成员函数)由某个对象调用。
this指针的特点:
(1)this指针指向被调用的成员函数所属的对象(某个对象调用成员函数,this指针即指向该对象)。
(2)this指针是隐含在每个非静态成员函数内的一种指针。
(3)this指针无需定义,可直接使用。
this指针的本质:this指针本质是指针常量
,等价于数据类型* const this
,即指针的指向不可修改,但指向的值可以修改。
this指针的作用:
(1)当成员变量与函数形参同名时,可使用this指针
区分,解决名称冲突。
(2)在类的非静态成员函数中,*this
可表示对象本身。return *this;
可返回当前对象:
①当函数以值类型返回,即返回类型为类类型
,会调用拷贝构造函数创建并返回当前对象的拷贝
;
②当函数以引用类型返回,即返回类型为类类型 &
,会返回当前对象本身
。
注1:
this
是指向对象的指针,可通过解引用操作*this
获取对象。
注2:this->成员属性
等价于(*this).成员属性
。
总结:
①函数中创建并返回临时对象时,函数返回类型应为值类型即类类型
,而不能为引用类型。
原因:临时变量在函数调用完毕后释放,若返回类型为引用类型即为同一个对象,访问已被释放的内存为非法操作;应返回值类型,创建临时对象的拷贝并返回。
②为保证链式编程风格或调用的对象全局唯一时,函数返回类型应为引用类型即类类型 &
,而不能为值类型。
原因:若返回类型为值类型,会创建当前对象的拷贝并返回,调用与返回的对象不是同一个对象;应返回引用类型,保证调用与返回同一个对象。
示例:
#include <iostream>
using namespace std;
class Account {
public:
int balance;
/* 使用this指针区分成员变量与函数形参同名的冲突 */
Account(int balance) {
//this->成员属性 等价于 (*this).成员属性
//(*this).balance = balance;
this->balance = balance;
}
//以【引用类型】返回
Account& sum1(Account a) {
this->balance += a.balance;
return *this; //返回当前对象
}
//以【值类型】返回
Account sum2(Account a) {
this->balance += a.balance;
return *this; //返回当前对象的拷贝
}
};
int main() {
Account a(10);
Account b(0);
Account c(0);
/* 链式编程 */
//以【引用类型】返回————返回当前对象本身
b.sum1(a).sum1(a).sum1(a);
cout << b.balance << endl; //30
//以【值类型】返回————返回当前对象的拷贝
c.sum2(a).sum2(a).sum2(a);
cout << c.balance << endl; //10
return 0;
}
3 空指针访问成员函数
C++中,空指针可调用成员函数。
若成员函数中访问成员变量时(即隐含地使用this指针
时),需进行判空处理以保证代码的健壮性。
//判空代码
if(this == NULL){
return;
}
示例:空指针访问成员函数
//空指针访问成员函数
#include <iostream>
using namespace std;
class Object {
public:
int field;
//成员函数中未访问成员变量(未使用this指针)
void print() {
cout << "Hello" << endl;
}
//成员函数中访问成员变量(使用this指针)
void func() {
/* 判空处理 */
if (this == NULL) {
return;
}
cout << field << endl; //访问成员变量时,等价于 this->成员变量
}
};
int main() {
//空指针
Object* obj = NULL;
/* 空指针访问成员函数 */
obj->print(); //程序正常:Hello
obj->func(); //未判空处理时,程序崩溃
system("pause");
return 0;
}
4 const修饰成员函数(常函数与常对象)
4.1 常函数
常函数:成员函数的形参列表后,使用关键字const
修饰。
语法:返回类型 函数名() const {...}
特点:常函数内,成员变量不可修改。
本质:成员函数后使用关键字const
修饰,本质相当于修饰this指针
(指针常量),则this指针
指向的值亦不可修改。
注1:
this指针
的本质是指针常量
,等价于数据类型* const this
,即指针的指向不可修改,但指向的值可以修改。
注2:
普通成员函数中,成员变量
等价于this->成员变量
,this
等价于数据类型* const this
。
常函数中,this
等价于const 数据类型* const this
,则this->成员变量
指针的指向与指向的值均不可修改。若修改常函数中的成员变量的值,则编译器报错:表达式必须是可修改的左值
。
注3:当成员属性声明时,若使用关键字mutable
修饰,则在常函数中仍然可以修改。
4.2 常对象
常对象:对象在声明时,使用关键字const
修饰。
特点:
(1)常对象的成员变量不可修改;
(2)常对象只能调用常函数。
注1:当成员属性声明时,若使用
关键字mutable
修饰,则在常对象中仍然可以修改。
注2:常对象不可调用普通成员函数,因为普通成员函数中成员属性可修改,与常对象的成员变量不可修改相斥。否则,编译器报错:对象含有与成员函数XXX::func()不兼容的类型限定符
。
示例:
#include <iostream>
using namespace std;
class Object {
public:
int field;
mutable int var;
/* 常函数:成员变量不可修改 */
//常函数中的const,本质相当于修饰this指针(指针常量),则this指针的指向与指向的值均不可修改
void func() const {
//field = 1; //报错:表达式必须是可修改的左值
var = 2; //使用mutable声明的成员变量,在常函数中仍可修改
}
/* 普通成员函数 */
void func2() {
field = 1;
var = 2;
}
};
int main() {
/* 常对象:常对象的成员变量不可修改;常对象只能调用常函数 */
const Object obj;
/* 常对象的成员变量不可修改 */
//obj.field = 1; //报错:表达式必须是可修改的左值
obj.var = 2; //使用mutable声明的成员变量,在常对象中仍可修改
/* 常对象只能调用常函数 */
obj.func();
//obj.func2(); //报错:对象含有与成员函数Object::func2()不兼容的类型限定符;对象类型是const Object
return 0;
}
最后
以上就是眯眯眼小蜜蜂最近收集整理的关于C++类和对象(三):C++对象模型和this指针1 成员变量和成员函数分开存储2 this指针3 空指针访问成员函数4 const修饰成员函数(常函数与常对象)的全部内容,更多相关C++类和对象(三):C++对象模型和this指针1内容请搜索靠谱客的其他文章。
发表评论 取消回复