4.3 C++对象模型和this指针
1.成员变量和成员函数分开储存
C++中成员函数和成员对象分开储存
1.只有非静态成员变量才属于类的对象上,非静态成员变量占对象空间;
2.静态成员变量不占对象空间;
3.函数也不占对象空间,所有函数共享一个函数实例;
4.静态成员函数也不占对象空间;
每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码;
空对象占用内存空间为1(C++编译器给每个对象分配)
空对象也要有独一无二的内存空间,一个字节是为了区分空对象占内存的位置。
内存对齐:结构体总大小,必须是内部最基本成员整数倍;
2.this指针概念
1.this指针指向被调用的成员函数所属的对象(类的对象,类是对象的抽象,对象是类的实例);
2.this指针是隐含每一个非静态成员函数内的一种指针;
this指针不需要定义,直接使用即可;
3.this指针的用途:
- 当形参和成员变量同名时,可用this指针来区分
- 在类的非静态成员函数中返回对象本身,可使用
return *this
- 如果用到this指针,需要加以判断保证代码的健壮性
返回引用与返回值的区别:用引用的方式返回不会创建新的对象,用值返回会产生新的对象。
为什么会有this指针?
1.每个非静态成员函数只会产生一份函数案例(多个同类型的对象共用一份代),代码通过this指针区分是哪个对象调用的。
2.创建一个对象后,不能通过对象使用this指针。也无法知道每个对象指针的位置(this指针在成员函数开始执行前构造,执行结束后清楚,只有在成员函数中才有this指针)
3.在成员函数中,可以知道this指针的位置(&this)
4.this指针本质:指针常量(指针指向的值不可以改变,指针的指向可以改变)
3.空指针
空指针:一个特殊的指针,这个指针可以不指向任何地方
Person * p = NULL;
可以用空指针访问成员,但是要防止出现无中生有导致崩溃,
在有this指针时更容易出现这种问题;
if(this==NuLL)
(return ;)
4.const修饰成员函数
-
加在成员函数后面:常函数
(此处const修饰的是this指针:让指针指向的值也不能修改)
const person *const this
person为类名
1.常函数内不可修改成员属性
2.成员属性声明加关键字mutable -
加在对象前面:常对象
常对象只能调用常函数
(普通成员函数可以修改属性,常函数不能修改成员属性)
4.4友元
- 在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术;友元的目的就是让一个函数或者类
访问另一个类中私有成员; - 友元关键字:
friend
- 友元的三种实现:
①全局函数做友元
②类做友元
③成员函数做友元
1全局函数做友元
class Building
{
//告诉编译器 goodGay全局函数 是 Building类的好朋友,可以访问类中的私有内容
friend void goodGay(Building * building);
public:
Building()
{
this->m_SittingRoom = "客厅";
this->m_BedRoom = "卧室";
}
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom; //卧室
};
void goodGay(Building * building)
{
cout << "好基友正在访问: " << building->m_SittingRoom << endl;
cout << "好基友正在访问: " << building->m_BedRoom << endl;
}
void test01()
{
Building b;
goodGay(&b);
}
int main(){
test01();
system("pause");
return 0;
}
2.类做友元
class Building;
class goodGay
{
public:
goodGay();
void visit();
private:
Building *building;
};
class Building
{
//告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容
friend class goodGay;
public:
Building();
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom;//卧室
};
Building::Building()
{
this->m_SittingRoom = "客厅";
this->m_BedRoom = "卧室";
}
goodGay::goodGay()
{
building = new Building;
}
void goodGay::visit()
{
cout << "好基友正在访问" << building->m_SittingRoom << endl;
cout << "好基友正在访问" << building->m_BedRoom << endl;
}
void test01()
{
goodGay gg;
gg.visit();
}
int main(){
test01();
system("pause");
return 0;
}
3.成员函数做友元
class Building;
class goodGay
{
public:
goodGay();
void visit(); //只让visit函数作为Building的好朋友,可以发访问Building中私有内容
void visit2();
private:
Building *building;
};
class Building
{
//告诉编译器 goodGay类中的visit成员函数 是Building好朋友,可以访问私有内容
friend void goodGay::visit();
public:
Building();
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom;//卧室
};
Building::Building()
{
this->m_SittingRoom = "客厅";
this->m_BedRoom = "卧室";
}
goodGay::goodGay()
{
building = new Building;
}
void goodGay::visit()
{
cout << "好基友正在访问" << building->m_SittingRoom << endl;
cout << "好基友正在访问" << building->m_BedRoom << endl;
}
void goodGay::visit2()
{
cout << "好基友正在访问" << building->m_SittingRoom << endl;
//cout << "好基友正在访问" << building->m_BedRoom << endl;
}
void test01()
{
goodGay gg;
gg.visit();
}
int main(){
test01();
system("pause");
return 0;
}