类&对象的概念及含义
- 面向对象程序设计
面向对象程序设计(Object Oriented Programming,OOP)是一种程序设计泛型,同时也是一种程序开发的方法。对象指的是类的实例,将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性、扩展性。
三大特性:
- 继承
- 封装
- 多态
- 访问限定符
- public成员可以从外部访问,但是<font color=red>protected和private</font>成员不能从外部直接访问。
- 每个限定符在类体中可以使用多次,它的作用域是从该限定符出现开始到下一个限定符之前或类体结束前。
- 类体中如果没有定义限定符,则默认为私有.
- 类的访问限定符体现了面向对象的封装性。
作用域
- 想要类一直存在,可以在类名之前加static。
- 对象可以通过.直接访问公有成员,指针对象的指针通过->也可以直接访问对象的共有成员。
- 在类外定义成员,需要使用::作用域解析符来指明成员属于哪个类域。
#include<iostream>
using namespace std;
class Person {
public: //公有的成员变量
char* _name;//成员变量名前尽量加_
char* _sex;
int age;
public: //共有的成员函数
void Information() {
cout << age << "岁的" << _name << "的性别是" << _sex << endl;
}
};
int main() {
Person p;//使用类名 对象名 实例化一个对象p
p._name = "可可";//通过.访问公有成员
p._sex = "女";
p.age = 24;
p.Information();//通过.调用成员函数
return 0;
}
类实例化对象
- 类只是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的空间来存储它。
- 一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间存储类成员变量。
类对象存储模型
计算类的大小要考虑成员变量和内存对齐,不考虑成员函数
为什么成员变量不占用空间?
- 因为在实际操作中,会实例化很多的对象,而很多的对象都会调用同一个成员函数,如果如果每实例化一个对象就要为他的成员函数开辟一块空间,那么很多的成员函数会浪费很多额外的空间,所以在公共代码区开辟了空间存储该类的成员函数。
请看下面两段代码:
#include<iostream> using namespace std; class A { char ch; double d; }; class B { char ch1; A a; char ch2; }; class C { }; class D { void fun(); }; int main() { cout << sizeof(A) << endl; cout << sizeof(B) << endl; cout << sizeof(C) << endl; cout << sizeof(D) << endl; return 0; }
- 输出结果16、32、1、1。
- 前两个依据的是内存对齐,类似于结构体内存对齐。
- 后两个证明了成员函数在类中不占用空间,但是为什么值是1不是0呢?可以粗略的理解为:当实例化出对象后给1个空间来标识对象在程序世界中存在过,而不是为了存储数据。试想,一个可爱的空类的对象被创建出来,但是如果类的大小是0,那么这个对象应该被创建在哪里?无处可去。
- 复习结构体内存对齐规则:
- 第一个成员变量在与结构体变量偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
- 对齐数=编译器默认的对齐数 与 成员大小的最大值 二者之间的最小值
- VS中默认8
- gcc默认4
- 结构体总大小为最大对齐数(每个成员变量除了第一个成员都有一个对齐数)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体对其到自己的最大对齐数的整数倍,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。