类定义格式
- 为了区分成员变量,一般习惯上成员变量会加上一个特殊标识,如成员变量前面或者后面加上_,m。注意:这个不是强制的,只是一些惯例。
- C++中 struct 也可以定义类 ,C++兼容C中struct的用法,同时struct升级成了类,明显的变化是struct中可以定义函数。一般我们还是推荐用class定义类。
- 定义在类中的成员函数默认为inline。
- 关于类的基本格式,我们可以看下面代码的注释哦~
#include<iostream>
using namespace std;
class date //class:关键字 date:类的名字
{
//类的主体
//类体中的内容称为类体成员
public:
void print()
{
cout << _year << " " << _month << " " << _day << endl;
}
//类的函数称为类的方法或者成员函数
private:
int _year;
int _month;
int _day;//类中的变量称为类的属性或者成员变量
};//;不能省略哦~
int main()
{
return 0;
}
访问限定符
可能大家会疑惑上面代码里的public和private是什么,它就是我们的访问限定符,下面我来为大家解释:
- 访问限定符是C++中一种实现封装的方式,用类将对象的属性和方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。
- public修饰的成员在类外可以直接被访问;
- protected和private修饰的成员在类外不能直接被访问。protected和private是一样的,在以后的继承章节才能体现出他们的区别。
- 访问权限作用域从访问限定符的出现到下一个访问限定符出现为止,如果后面没有访问限定符了,就到类结束为止。
- class定义成员没有被访问限定符修饰时默认为private,而struct则默认为public。
#include<iostream>
using namespace std;
//证明class里默认为private
class student
{
int _cn;
int _math;
int _en;
public://1
int sumgrade(int cn, int math, int en)
{
_cn = cn;
_math = math;
_en = en;
return (cn + math + en);
}//1.从上面的1到这里是public的访问权限作用域。
};
int main()
{
student s1;
s1.sumgrade(100, 100, 100);
cout << s1._cn << endl;
//报错:成员 "student::_cn" 已声明 不可访问
return 0;
}
证明struct里默认为public:
#include<iostream>
using namespace std;
struct student
{
int _cn;
int _math;
int _en;
int sumgrade(int cn, int math, int en)
{
_cn = cn;
_math = math;
_en = en;
return (cn + math + en);
}
};
int main()
{
struct student s1;
s1.sumgrade(100, 100, 100);
cout << s1._cn << endl;
return 0;
}
- 一般来说,成员变量都会被限制为private/protected,需要给别人使用的成员函数会放在public.
有的朋友可能会疑惑,为什么在类之中我们可以把要使用的变量放在成员函数下面?
这是因为在C++中,类的成员变量和成员函数的声明顺序并不影响它们在类中的可见性。因为C++编译器在处理类定义时,会先解析类的整个声明,再生成代码。所以,即使成员变量在成员函数之后声明,成员函数仍旧可以访问这些成员变量 。
类域
- 类定义了一个新的作用域,类的所有成员都在类的作用域中,在类外定义成员时,需要使用::作用域操作符指明成员属于哪个类域。
- 类域影响的是编译的查找规则
#include<iostream>
using namespace std;
class student
{
public:
void print();
private:
int _cn;
int _math;
int _en;
};
void student::print()//声明和定义分离,需要指定类域。
{
cout << "!" << endl;
}
实例化
实例化概念
- 用类类型在物理内存中创建对象的过程,称类实例化出对象。
- 类是对象进行一种抽象描述。类声明的成员变量只是声明,没有分配空间,用类实例化出对象时,才会分配出空间。
- 一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,储存成员变量。
对象大小
类实例化出的每个对象都有独立的数据空间,所以对象中肯定包含成员变量,那么成员函数是否包含呢?
我们知道函数被编译后是一段指令,对象中无法储存,所以即使要储存,也是储存函数的指针。
C++规定类实例化的对象也要符合内存对齐的规则。
内存对齐的好处是:
由于硬件设计是整数读的,不用一次次访问然后再拼起来,访问快。本质是用空间换时间。
内存对齐规则
• 第一个成员在与结构体偏移量为0的地址处。
• 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
• 注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
• VS中默认的对齐数为8
• 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
• 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小。
就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
注意:
#include<iostream>
using namespace std;
class B
{
public:
void print()
{
//......
}
};
class C
{
};
int main()
{
cout << sizeof(B) << " " << sizeof(C) << endl;
return 0;
}
没有成员变量的B和C类对象的大小是1。若是不给字节,怎么表示对象存在过呢?所以我们给一字节,为了占位表示对象存在。