手机网站素材网,公司品牌的塑造网站建设,杭州比较有名的设计公司,wordpress 去掉头部文章目录类的概念structclassclass和struct的区别是什么呢#xff1f;类中成员函数的两种定义方式声明和定义都在类中声明和定义分离类的访问控制和封装类的封装特性类的大小结构体内存对齐规则类的存储方式this指针类的概念
在C中#xff0c;类可以说是最重要的东西#x…
文章目录类的概念structclassclass和struct的区别是什么呢类中成员函数的两种定义方式声明和定义都在类中声明和定义分离类的访问控制和封装类的封装特性类的大小结构体内存对齐规则类的存储方式this指针类的概念
在C中类可以说是最重要的东西因为C一开始的定位就是c with class,也正是因为引入了类才让c从c的面向过程思想转变为面向对象的思想关注的是对象将一件事情拆分成不同的对象靠对象之间的交互完成。
C有两种能够创建类的方法
struct
第一种是struct也就是从C继承而来的在C语言中struct可以用来创建结构体但是结构体中只能保存变量而不能保存函数在C中struct不仅可以用来创建类还保留了C语言中结构体的用法
struct Date
{void PrintDate(){cout _year - _month - _day endl;}int _year;int _month;int _day;
};class
class是C中定义类的关键字他的用法和struct类似。
在类中类的元素被称为类的成员类中的数据被称为成员变量或者类的属性类中的函数被称为类的方法或者成员函数
class Date
{void PrintDate(){cout _year - _month - _day endl;}int _year;int _month;int _day;
};class和struct的区别是什么呢
C兼容C语言所以struct不仅可以定义类还可以当成结构体使用。访问限定不同struct的成员默认访问方式为publicclass为private 并且struct默认继承为public继承class为private 类中成员函数的两种定义方式
声明和定义都在类中
如果成员函数在类内部定义则其是隐式的inline函数。
class Date
{void PrintDate(){cout _year - _month - _day endl;}int _year;int _month;int _day;
};声明和定义分离
在类内声明在类外定义这样能让类更加简洁不那么臃肿通常都是使用这种方式。
class Date
{void PrintDate();int _year;int _month;int _day;
};//需要通过作用域运算符指定这个方法属于Date类
void Date::PrintDate()
{cout _year - _month - _day endl;
}类的访问控制和封装
访问限定符有三种分别是public,private,protected
public修饰的成员在类外可以直接被访问。protected和private修饰的成员在类外不能直接被访问protected修饰内容派生类可以访问private不可以。访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。
类的封装特性 封装将数据和操作数据的方法进行有机结合隐藏对象的属性和实现细节仅对外公开接口来和对象进行 交互。 封装本质上是一种管理我们如何管理兵马俑呢如果什么都不管兵马俑可能会被随意破坏。那么我们首先建了一座房子把兵马俑给封装起来。但是我们目的并不是全封装起来不让别人看。所以我们开放了售票通道可以通过买票突破封装、在合理的监管机制下进去参观。类也是一样我们将类数据和方法都封装一下。不想给别人肆意修改我们使用protected/private把成员封装起来。同时开放一些共有的成员函数对成员合理的访问机制。所以封装本质是一种管理。
一般对于对象的属性我们不希望别人对它进行修改所以会用private将其封装但是我们又需要给别人提供获取它的接口所以会对方法和接口给与public属性。 类的大小
class Date
{
public:void PrintDate();private:char a;int _year;int _month;int _day;
};我们可以看到类中有成员函数有成员变量那么类的大小是如何计算的呢
int main()
{Date d;cout sizeof(d) endl;
}这里用sizeof查看大小发现只有成员变量的大小三个int类型一个char类型3*4113这里的16是因为内存对齐偏移了3个字节而没有成员函数的大小
结构体内存对齐规则
第一个成员在与结构体偏移量为0的地址处。其他成员变量要对齐到某个数字对齐数的整数倍的地址处。 注意对齐数 编译器默认的一个对齐数 与 该成员大小 两者中的较小值。(如int大小为4VS中默认的对齐数为8取4)结构体总大小为最大对齐数所有变量类型最大者与默认对齐参数取最小本例中所有变量类型最大者是int大小为4与默认对齐参数取最小则为4的整数倍。如果嵌套了结构体的情况嵌套的结构体对齐到自己的最大对齐数的整数倍处结构体的整体大小就是所有最大对齐数含嵌套结构体的对齐数的整数倍。
类的存储方式
为什么会只保存了成员变量呢这里就要引申出类的存储方式。
对于上面的类如果我们将类实例化为多个对象实际上这些对象不同的地方只有它的属性它们调用的方法都是完全相同的 为了不重复保存这些代码C只保存了属性而将方法放到了公共的代码段中来避免了空间的浪费。 同时如果一个类中什么都没有编译器会给这个类一个字节来唯一标识这个类。 总结类的大小就是成员变量之和需要考虑内存对齐 this指针
void Date::PrintDate()
{cout _year - _month - _day endl;
}对于类中的成员函数我们并没有将对象的属性传给他那么他是如何能够获取这些属性的呢 C编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数this指针让该指针指向当前对象(函数运行时调用该函数的对象)在函数体中所有对成员变量的操作都是通过该指针去访问。只不过所有的操作对用户是透明的即用户不需要来传递编译器自动完成。 其实类的成员函数中隐含了一个this指针所以在编译器处理的时候上面的代码等价于
void Date::PrintDate(Date * const this)
{cout this-_year - this-_month - this-_day endl;
}这个this指针的类型是类类型 * const this之所以是顶层const的原因是因为this指针唯一指向对象地址。this指针只能在成员函数中使用this指针本质上其实是一个成员函数的形参是对象调用成员函数时将对象地址作为实参传递给this形参。所以对象中不存储this指针this指针存在寄存器中。this指针是成员函数第一个隐含的指针形参一般情况由编译器通过ecx寄存器自动传递不需要用户传递
同时如果this指针为空时成员函数使用到了this指针则会崩溃如果没使用则正常运行