2022.01.25 学习记录
4.2 对象的初始化和清理
4.2.6 初始化列表
其实初始化列表是构造函数的一种初始化方式。
class person{
public:
// 传统初始化
// person(int a, int b, int c)
// {
// m_A = a;
// m_B = b;
// m_C = c;
// }
// 初始化列表
// 括号后面加上冒号,变量名再加上括号
person(int a, int b, int c):m_A(a), m_B(b), m_C(c)
{
}
int m_A;
int m_B;
int m_C;
};
4.2.7 类对象作为类成员
对象再另一个类中作为成员。
phone类的对象p_Phone在新的类person中。
先调用类成员的构造函数,再调用类的构造函数,析构函数顺序相反。
class phone{
public:
phone(string pName)
{
m_PName = pName;
cout << "phone constructor" << endl;
}
string m_PName;
~phone(){
cout << "phone destructor" << endl;
}
};
class person{
public:
person(string name, string pName):m_Name(name), m_Phone(pName)
{
cout << "person constructor" << endl;
}
string m_Name;
// phone类的对象p_Phone在新的类person中
phone m_Phone;
~person(){
cout << "person destructor" << endl;
}
};
4.2.8 静态成员
静态函数只能调用静态变量。
静态函数可以由对象访问,也可以由类名访问。
int person::m_A = 0; 静态成员变量必须定义。
class person
{
public:
static void func()
{
m_A = 100;
// m_B = 200;// 只能访问static
cout << "static void func()" << endl;
}
static int m_A;
int m_B;
// 访问权限
private:
static void func2()
{
cout << "static void func2()" << endl;
}
void func3()
{}
};
int person::m_A = 0;
void test01()
{
// 1.对象访问
// person p;
// p.func();
// 2.类名访问
person::func();
}
4.3 C++对象模型和this指针
4.3.1 成员变量和成员函数分开存储
class person
{
int m_A; // 非静态成员变量
static int m_B; // 静态成员变量,不属于任何对象
void func() {} // not static ,不属于类的对象
static void func2(){}
};
int person::m_B = 0;
void test01()
{
person p;
// 空对象占用的内存空间:1byte
// 空对象也会分1个字节,为了区分对象占用空间的位置
// 每个空对象也应该有独一无二的内存地址
cout << "size of p = " << sizeof(p) << endl;
}
4.3.2 this指针的概念
this指针的引入主要是为解决两大问题:
- 解决名称冲突
- 返回对象本身
class person
{
public:
person(int age)
{
// this 指向的是:被调用成员函数所属对象
this->age = age;
}
// 如果不用引用,就会返回一个新的对象
person& PersonAddAge(person &p)
{
this->age += p.age;
// this是指向p2的指针,*this就是p2
return *this;
}
int age;
};
void test01()
{
person p1(18);
cout << "p1的年龄=" << p1.age << endl;
}
void test02()
{
person p1(10);
person p2(10);
p2.PersonAddAge(p1).PersonAddAge(p1);
cout << "p2's age = " << p2.age << endl;
}
4.3.3 空指针访问成员函数
空指针可以调用成员函数,看有没有用到this指针
class person
{
public:
void showClassName()
{
cout << "This is person class; " << endl;
}
void showPersonAge()
{
if (this == NULL)
return;
// 传入指针为空,没有对象还想访问对象的年龄
cout << "age = " << this->m_Age << endl;
}
int m_Age;
};
void test01()
{
person *p = NULL;
// p->showClassName();
p->showPersonAge();
}
4.4.4 const修饰成员函数
常函数:
1、成员函数后加const,就叫常函数
2、常函数不可以修改成员属性
3、成员属性声明的时候加mutable后,在常函数中依旧可以修改
常变量:
1、声明对象前加const
2、常对象只能调用常函数
#include <iostream>
using namespace std;
class person
{
public:
/**
// 成员函数内部都有一个this指针
// this指针的本质:指针常量,指向不可以修改
// person * const this;
// 如果值也不让改
// const person * const this;
// 成员函数后面加const,修饰的是this指针,让指针指向的值也不可以修改
*/
void showPerson() const
{
// this->m_A = 100;
// this = NULL; // this不可以修改朝向
this->m_B = 100;
}
void func()
{
}
int m_A;
// 特殊变量,即使在常函数中,也可以修改
// 加上mutable
mutable int m_B;
};
void test01()
{
person p;
p.showPerson();
}
// 常对象
void test02()
{
const person p{};
p.m_A = 100;
p.m_B = 100; // 常对象下也可以修改
// 常对象只能调用常函数
p.showPerson();
// 报错
p.func();
}