一、面向过程和面向对象初步认识
![](https://img-blog.csdnimg.cn/direct/fc8819be5f8d45fb9ecb5be4a21a199d.png)
![](https://img-blog.csdnimg.cn/direct/b00712f76d68428cb0b2d2f55a11e8ac.png)
二、类的引入
C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。现在以C++方式实现,会发现struct中也可以定义函数。
struct A1
{
int* a;
int b;
int Add(int x, int y)
{
return x + y;
}
};
上面结构体的定义,在C++中更喜欢用class来代替。(把struct改为class)
class A1
{
int* a;
int b;
int Add(int x, int y)
{
return x + y;
}
};
三、类的定义
class className
{
//类体:由成员函数和成员变量组成
};//一定要注意后面的分号
(1)生命和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会当成内联函数来处理。
(2) 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::
建议:少用第一种定义类,多用第二种方式定义类。
四、类的访问限定符及封装
1、访问限定符
![](https://img-blog.csdnimg.cn/direct/ad304f05f60b4c7f99f536d8875af6fc.png)
5. class的默认访问权限为private,struct为public(因为struct要兼容C)
注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别
2、封装
五、类的作用域
class Person//Person是类名
{
public:
void PrintPerson();
private:
int _name[20];
int _gender[3];
int _age;
};
void Person::PrintPerson()//PrintPerson术语Person这个类域
{
cout << _name << " " << _gender << " " << _age << endl;
}
六、类的实例化
用类类型创建对象的过程,称为类的实例化。
1. 类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它;比如:入学时填写的学生信息表,表格就可以看成是一个类,来描述具体学生信息。
2. 一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量。
做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。
错误示范:
Person类是没有空间的,只有Person类实例化出的对象才有具体的年龄。
正确示范:
Person 实例化出的对象是man,man具有名字、年龄、性别等。
七、类的对象大小的计算
//类中既有成员变量,又有成员函数
class A1
{
public:
void f1()
{
//
}
private:
int _a;
};
//类中只有成员函数
class A2
{
public:
void Func2()
{
//
}
};
//空类
class A3
{
};
int main()
{
cout << "A1所占空间:" << sizeof(A1) << endl;//打印结果为4
cout << "A2所占空间:" << sizeof(A2) << endl;//打印结果为1
cout << "A3所占空间:" << sizeof(A3) << endl;//打印结果为1
return 0;
}
结论:一个类的大小,实际就是该类中”成员变量”之和,当然要注意内存对齐注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。
结构体内存对齐规则:
八、类成员函数的this指针
1、this指针的引出
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2;
d1.Init(2024, 5, 21);
d2.Init(2024, 5, 20);
d1.Print();//打印结果为2024/5/21
d2.Print();//打印结果为2024/5/20
return 0;
}
![](https://img-blog.csdnimg.cn/direct/eaa46a488aaa4754a05812527eb420cc.png)
![](https://img-blog.csdnimg.cn/direct/e5c8c36874d04839abca1c7fdb50c003.png)
编译器进行编译时,给我们看到的形参实际上不一样。第一个形参实际上是隐含的this指针,该this指针用于调用函数的对象的地址,用this指针就可以很好地访问到该对象中的成员变量:
我们看到的形参:
实际上的形参:
2、this指针的特性
![](https://img-blog.csdnimg.cn/direct/d389e4600d3749a7900a72aa04c88745.png)
this指针有关练习:
class Date
{
public:
void Print()
{
cout << "Print()" << endl;
}
void Show()
{
cout << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date* p = nullptr;
//p->Print();//正常打印
//p->Show();//程序会崩溃
}
Print()会正常打印,因为Print() 函数是在公共代码区,没有解引用p指针。而show()函数会崩溃,show函数也是在公共代码区,但是函数里面打印的成员变量“_day","_day"只有通过this指针解引用才能访问,而this指针现在是空指针,对空指针进行解引用必然会导致程序的崩溃。