类与对象:静态成员、c++对象模型和this指针
一、静态成员分类
一)、静态成员变量
1、特性
所有对象共享一份数据(对象访问时不能是私有权限)
编译阶段分配内存
类内声明,类外初始化
#include<iostream>
using namespace std;
#include<string>
class person
{
public:
string m_name;
static string m_company;
person(string name)
{
m_name = name;
cout << "调用构造函数" << endl;
}
~person()
{
cout << "调用析构函数" << endl;
}
};
string person::m_company = "荣耀";//静态成员变量类外初始化,初始化时需要加作用域,并且属于类的所有对象
int main()
{
person p1("张三");
cout << "姓名:" << p1.m_name << "公司:" << p1.m_company<<endl;
}
2、内存管理
静态成员变量在全局区,还有全局变量。
二)、静态成员函数
1、特性
所有对象共享一个函数(不能是私有权限)
静态成员函数只能访问静态成员变量
2、语法
static 数据类型 函数名()
例如:static void set()
3、调用
通过对象调用
通过类名调用:person::set();//因为它是共享的不属于某一个对象
注意:类外访问不包括私有成员函数
二、c++对象模型和this指针
一)、成员变量和成员函数分开存储
注意:只有非静态成员变量才属于类的对象上,所以创建对象利用sizeof输出对象的的内存都是为4个字节,若是空对象为1个字节,因为编译器为了区分空对象的内存位置。
二)、this指针
前言:由于只有非静态成员变量类在对象上,不同对象与变量一一对应配套,那么不同对象在调用非静态成员函数会共用一段代码,那么这一块代码是如何区分哪一个对象调用的呢?
所以通过this指针指向被调用成员函数的对象!!!
1、定义
this指针是隐藏在非静态成员函数内的指针,不需要定义。哪个对象调用,this指向谁。记忆:this指针和对象一一对应
2、用途
1、形参和成员变量同名时,用this指针区分
操作时,编译器会认为它们都是一样的
person(string m_name)
{
m_name = m_name;
cout << "调用构造函数" << endl;
}
问题:无法给姓名赋值
解决办法:养成习惯,形参和成员变量名写得不一样
this指针区分
person(string m_name)
{
this->m_name = m_name;
cout << "调用构造函数" << endl;
}
2、非静态成员函数返回对象本身时,可以返回*this
void addperson(person& p)//返回对象本身
{
this->m_age += p.m_age;
}
```cpp
#include<iostream>
using namespace std;
#include<string>
class person
{
public:
int m_age;
person(int m_age)
{
this->m_age = m_age;
cout << "调用构造函数" << endl;
}
~person()
{
cout << "调用析构函数" << endl;
}
void addperson(person& p)//返回对象本身
{
this->m_age += p.m_age;
}
};
void test01()
{
person p1(10);
cout << p1.m_age << endl;
}
void test02()
{
person p1(18);
person p2(18);
p1.addperson(p2);
cout << "p1的年龄:" << p1.m_age << endl;
}
int main()
{
test02();
}
p1调用的非静态成员函数,所以该函数内this指向的是p1。所以对于多个对象作为形参操作时,不用定义两个形参了。可以结合this指针和一个形参的引用。
由于返回的是p1,可以无限调用成员函数(链式编程)。但是会出错,因为addperson返回的是void,所以第一次调用后就会置0。
void test02()
{
person p1(18);
person p2(18);
p1.addperson(p2).addperson(p2);
cout << "p1的年龄:" << p1.m_age << endl;
}
若修改addperson的返回类型为person &,返回对象本体如下:
person& addperson(person& p)//返回对象本身
{
this->m_age += p.m_age;
return *this;//返回的是对象本身
}
void test02()
{
person p1(18);
person p2(18);
p1.addperson(p2).addperson(p2);
cout << "p1的年龄:" << p1.m_age << endl;
}
若返回的是值,则后续不会相加,和第一次一样.因为返回的是值时就得联系何时调用拷贝构造函数了。
person addperson(person& p)//返回对象本身
{
this->m_age += p.m_age;
return *this;//返回的是对象本身
}
void test02()
{
person p1(18);
person p2(18);
p1.addperson(p2).addperson(p2);
cout << "p1的年龄:" << p1.m_age << endl;
}
三、空指针调用成员函数
本来是直接输出m_age,由于成员变量在对象上,其实本质上也有this->m_age。但是this为空,所以输入错误
为了不出错