一.类的定义
1.1类的创建
类是C++中用户自己建立的类型。类似于C语言中的结构体。定义类的关键字为class。格式为:
class 类名
{
成员函数
成员变量
……
};
class 类名称为类头,花括号中的称为类体。类的声明以花括号后的分号结束,分号不可省略。在一个类中,既可以有成员变量,即类的属性;也可以有成员函数,即类的行为。而C语言阶段学习的结构体则只有成员变量。
C++中,类中的成员变量为了与其他变量区分,其成员变量建议在名字前加上下划线。
下面定义一个学生类:
class student
{
void GetStudentinfor()
{
cout << _name << endl << _age << endl << _id << endl;
}
char _name[15];//姓名
int _age;//年龄
char _id[20];//学号
};
该类中的姓名、年龄、学号都是成员变量,而获取学生信息是成员函数,它的功能是打印学生信息。
1.2访问限定符
一个类会将一组数据和操作封装在一起,对外界是隐蔽的,在类外不能直接调用类中的成员。这虽然很安全,但是程序要怎么才能执行其中的操作呢?一般,我们只需要将数据隐藏起来,而将函数作为对外界的接口,实现各种操作。
C++提供了访问限定符:private(私有)、public(公有)、project(保护)。我们可以通过访问限定符对类中的成员进行修饰限定。当成员被private修饰时,表示该成员不能被类外直接访问,只能通过类的成员函数访问;当成员被public修饰时,表示该成员可以被类外直接访问;project也只能被成员函数访问,不能直接被类外访问。
当我们创建类时不指定访问限定符时,class会默认类中的成员全都为private。
所以,有了访问限定符,我们定义类时就应该对成员进行修饰限定:
class 类名
{
public:
成员函数
private:
成员变量
};
通常,我们将成员变量定义为private,将成员函数定义为public。成员限定符可以在一个类体中多次出现,但是建议将具有同一属性的成员写在一块。
在定义类时,将类的成员函数写在前面,将类的成员变量写在后面。
下面我们对刚才的studen类进行修改:
class student
{
public:
void GetStudentinfor()
{
cout << _name << endl << _age << endl << _id << endl;
}
private:
char _name[15];//姓名
int _age;//年龄
char _id[20];//学号
};
1.3类域
定义类时就形成了一个新的作用域,该作用域不会改变成员变量的生命周期,只是对成员变量加以限制。
一般我们类中的成员函数都是在类体中直接定义的,但是如果只是在类体中声明,在类外定义的话,需要借助作用域运算符来说明该成员函数或者成员变量是属于哪一个类的。否则该函数就是一个普通函数,可以被任何人调用,不可以访问类中的私有成员变量。
在类外定义成员函数的格式为:
返回值 类名::函数名()
{
}
class student
{
public:
void GetStudentinfor();//声明
private:
char _name[15];//姓名
int _age;//年龄
char _id[20];//学号
};
//定义
void student::GetStudentinfor()
{
cout << _name << endl << _age << endl << _id << endl;
}
二.类的实例化
我们定义好了类,但是类只是我们定义的一个自定义类型而已,它就好比一个设计图纸,是没有大小的,当我们利用该图纸建造了房子,这就是一种实例化的体现。所以类的实例化其实就是用类建立对象的过程。
student s1;
student s2;
我们利用我们定义的类创建了两个对象s1和s2,这就是类的实例化。
2.1对象的大小
对象的大小是怎么计算的呢?我们用同一个类创建的不同对象除了成员变量不同外,其他的都是相同的。那么对象在内存中的存储是即存储变量也存储函数么?如果这样的话,同一份相同的代码要储存多少份呢?所有的对象调用成员函数时都是调用的同一份代码,这成员函数存储在内存中的某一个地方,但是并不在对象中。
所以对象的大小是不包括成员函数的,只包含成员变量。而其大小的计算方式与C语言中结构体大小的计算方式相同,采用内存对齐的方式存储。
内存对齐的规则
- 第⼀个成员在与结构体偏移量为0的地址处。
- 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。
- 注意:对⻬数=编译器默认的⼀个对⻬数与该成员⼤⼩的较⼩值。
- VS中默认的对⻬数为8
- 结构体总⼤⼩为:最⼤对⻬数(所有变量类型最⼤者与默认对⻬参数取最⼩)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体对⻬到⾃⼰的最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体的对⻬数)的整数倍。
特别要注意的是,当一个类只有成员函数没有成员变量的时候,以该类创建的对象的大小不是0而是1.
三.this指针
当我们用同一个类创建了两个对象a,b,而它们调用的是同一份函数代码,那么该函数怎么确定使用哪一个对象的成员变量呢?
在每一个成员函数中都包含一个特殊的指针,这个指针的名字是固定的,称为this。它是指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起始地址。
所以当我们调用studeng类中的GetStudentinfor时,看似没有传参数,起始将调用该函数的对象的地址传给了该函数:
s1.GetStudentinfor();
//s1.GetStudentinfor(&s1)
而在该函数内部:
void student::GetStudentinfor(student* this)
{
cout << _name << endl << _age << endl << _id << endl;
//cout << this::_name << endl << this::_age << endl << this::_id << endl;
}
而this指针是隐式调用的,我们不需要管,但是this指针也可以显式的调用。需要注意的是,我们在传参数的时候不必传对象的地址,是隐式传递的。但是我们可以在函数内部显式的使用this指针。
四.struct和class的区别
struct原本是C语言中定义结构体的关键字,但是在C++中,struct得到了升级,它可以定义类,但是struct定义的类默认成员函数和成员变量都是公有的(public),而class定义的类默认成员函数和成员变量是私有的(private)。
完~