类和对象的初步认识
说起概念、读起概念都是一个枯燥无味的过程,在这里,首先用一个现实生活例子来类比,简单的描述一下类和对象。
就好比人类,就是一个类,是一个抽象的描述,而具体到某个人, 具体的这个人就是一个对象,对象是类的实例化。
每个人有不同的属性,即成员变量,还有相同的行为,即成员函数。
C语言虽然是面向过程的编程语言,但是C语言中已经存在有给面向对象铺垫的数据类型——结构体。结构体把若干个成员变量封在一起,但是C语言中的struct只有封装了若干个变量,C++完成了进一步更完善的封装,类类型不只是有属性,还封装了行为,行为即称为类的方法或者成员函数。
类和结构体一样,也是一种自定义的类型,用类类型创建一个对象的过程 即是 类的实例化。
简单的定义人这个类,代码如下:
以下代码自定义了“人”这个类,然后用人这个类类型创建了对象小红
class Person {
public:
char* name;
char* sex;
int age;
void showInfo() {
cout << name << " " << sex << " " << age << endl;
}
}
//小红即是“人”类创建的对象,即实例化对象
Person xiaohong;
类的访问限定符及封装
实现封装的方式:用类将对象的属性与方法结合在一块(上面的例子有所体现),让对象更完善,通过访问权限 选择性的将接口提供给外部的用户使用。
访问限定符:public(共有)、protected(保护)、private(私有)
说明:
1.public修饰的成员在类外可以直接访问
2.protected和private修饰的成员在类外不能直接被访问
3.访问权限作用域从该访问限定符出现的位置开始知道下一个访问限定符出现时为止
4.class的默认访问权限是private,struct为public(因为struct要兼容C)
注:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别
类对象的的大小
一个类的大小,实际就是该类中**“成员变量”之和**,也要进行内存对齐 ,空类的大小较特殊,编译器给了空类一个字节来唯一标识这个类。
“空类” 大小也拿一个形象的例子来理解,大学中常见的占座位来说,用自己的书占了一个座位,别人就会知道这个座位有人,同样的道理,空类用1个字节来标识这个类的存在。
下面代码A的大小为4,B的大小为1,C的大小为1;
//有成员函数也有成员变量
class A {
public:
void f1(){}
private:
int a;
};
//仅有成员函数
class B {
public:
void f2() {}
};
//空类
class C {};
结构体内存对齐规则
内存对齐的原因:是为了提高数据成员的访问效率
对齐规则:
- 第一个成员在与结构体偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
可以通过#pragma pack(size)设置默认对齐数为size。
VS中默认的对齐数为8,gcc中的对齐数为4。 - 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
this指针
C++编译器给每个“成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
1.this指针的类型:
类类型* const
2.只能在“成员函数”内部使用
3.this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存在this指针
4.this指针是成员函数第一个隐含的指针形参,一般情况有编译器通过ecx寄存器自动传递,不需要用户传递。
下面的display函数并不需要传入this指针,this指针时隐含的,只是为了理解才这样说明的。
class Date {
private:
int year;
int month;
int day;
public:
void display(Date* this) {
cout << this->year << "-"<< this->month << "-"<< this->day << endl;
}
}
下一篇博客将会说明类的默认成员函数,敬请期待。