类与对象(上-2)
6、类的实例化
Test.cpp
//用类类型创建对象的过程,称为类的实例化。
//类是对对象进行描述的,是一个 模型 一样的东西,来限定了类有哪些成员,定义一个类但并没有分配实际的内存空间来存储它。
//例如:设计出一个大楼的建筑模型,来指导大楼的实际建设。
int mian()
{
Person p1; //类的实例化
Person p2;
Person p3;
return 0;
}
F.h
#pragma once
#include <iostream>
using namespace std;
class Person
{
public:
void PrintPersonInfo(); //函数的申明
private:
char _name[20]; //变量的申明 (如何区分变量的申明和定义){申明:没有给变量开空间; 定义:给变量开了空间。}
char _gender[3]; //这儿的成员变量处于类内,没有开空间。当用类来实例化对象时,才开辟的空间。
int _age;
};
F.cpp
#include "Person.h"
//这里需要指定PrintPersonInfo是属于Person这个类域的
void Person::PrintPersonInfo() //函数的定义
{
cout << _name << " " << _gender << " " << _age << endl;
}
7、计算类空间的大小
//{虽然没有给类开辟空间,但是可以计算类占据空间的大小}
//(1)类的空间大小计算与结构体相似,都遵循内存对其原则。
//(2)只计算类内的成员变量,而成员函数不需要考虑(因为成员函数不存储在实例化对象内,而是存储在公共代码区)
//(3)特殊的类:(没有成员变量的类对象,大小为:1byte;占位不存储实际数据,标识对象存在)。
#include <iostream>
using namespace std;
class A
{
public:
void PrintA()
{
cout << _a << endl;
}
void FuncA()
{
cout << "FuncA()" << endl;
}
//private:
char _a;
};
int main()
{
//类的存储模式:成员变量存储在实例化对象内,成员函数存储在公共代码区。
//实例化的每个对象的成员变量是不同的变量,具有独立的空间;而从各个对象的成员函数角度分析,调用的成员函数是同一个。
//所以如果将成员函数每次都保存在对象内,会造成空间浪费。
A aa1;
A aa2;
aa1._a = 1;
aa2._a = 2;
aa1.PrintA(); //编译链接时,就根据函数名去公共代码区找到函数的地址 {call函数地址}。
aa2.PrintA();
A* ptr = nullptr;
ptr->FuncA(); //运行结果是:程序正常运行打印;因为对象的成员函数FuncA保存在公共代码区,不需要对ptr进行解引用(没有动空指针),不会出错。
return 0;
}
8、this指针
#include <iostream>
using namespace std;
class Data
{
public:
//实参和形参位置不能显示传递和接收this指针,但是可以在成员函数内部使用this指针
void Init(int year, int month, int day) //默认在参数的最前面加上: Data* const this (this本身不可修改,但是this指向的内容可以修改)
{
this->_year = year;
this->_month = month;
_day = day;
}
void Print() //默认加参数: Data* const this
{
cout << this->_year << "-" << _month << "-" << _day << endl;
}
private:
int _year; //类的成员变量命名在首字母前面加 _
int _month;
int _day;
};
int main()
{
Data d1; //虽然类的成员变量是私有的,无法在外面直接修改。但是可以通过调用成员函数去修改
d1.Init(2022, 7, 17);
Data d2;
d2.Init(2022, 7, 18); //默认在参数的最前面加:&d2
d1.Print(); //默认加参数:&d1
d2.Print();
return 0;
}
//this指针存储在栈区,this指针是形参。存在某些优化的情况下,this指针存储在寄存器。
练习题目:
#include <iostream>
using namespace std;
class A
{
public:
void PrintA()
{
cout << this << endl;
cout << _a << endl;
}
void Print()
{
cout << this << endl;
cout << "Print()" << endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
//p->Print(); //运行正常:程序正常运行打印;因为对象的成员函数FuncA保存在公共代码区,不需要对p进行解引用(没有动空指针),不会出错。
p->PrintA(); //运行崩溃:PrintA非法访问了空指针
return 0;
}