网站开发工程师的生活形态,网站上做地图手机上显示,专门做西装网站,重庆网站建设公目录
类的认识
访问限定符#xff1a;public(公有)#xff0c;protected(保护)#xff0c;private(私有)。
类的两种定义方式:
类的实例化#xff1a;
封装#xff1a;
类的对象大小的计算#xff1a;
类成员函数的this指针#xff1a; C语言是面向过程的语言public(公有)protected(保护)private(私有)。
类的两种定义方式:
类的实例化
封装
类的对象大小的计算
类成员函数的this指针 C语言是面向过程的语言关注的是过程分析求解问题的步骤通过函数调用逐步解决问题。
C是基于面向对象的语言关注的是对象将一件事拆分成不同的对象考对象之间的交互完成。
C语言结构体struct中只能定义变量在C中结构体内不仅可以定义变量也可以定义函数因为C将struct同时升级成了类类中可以定义函数。
如下:
struct Stack
{int* _a;int _top;int _capacity;void Init() {_a 0;_top 0;_capacity 0;}
};
在C中类名就是类型所以C在声明结构体变量时不需要在前面加struct,使用上面的Stack定义如Stack s1; 类的认识
在C中更喜欢用class来代替。 class className{ //类体:由成员函数和成员变量组成 };//注意分号 class为定义的关键字ClassName为类的名字{}中为类的主体类定义结束时后面分号不能省略。
类体中内容称为类的成员类中的变量称为类的属性或成员变量类中的函数称为类的方法或者成员函数。 访问限定符public(公有)protected(保护)private(私有)。
public修饰的成员在类外可以直接被访问。protected和private修饰的成员在类外不能直接被访问。访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。如果后面没有访问限定符作用域就到}即结束。class的默认访问权限为privatestruct为public(因为在C中的struct在类外都可以访问所以是公有)。注意访问限定符只在编译时有用当数据映射到内存后没有任何访问限定符上的区别。
如下代码:
class Stack
{
private:int* _a;int _top;int _capacity;
public:void Init() {_a 0;_top 0;_capacity 0;}bool Empty() {return _top 0;}
};
其中private下面的为私有的在类外不可以访问public下面的为公有在类外都可以访问。如果我在类外修改类内的a只需要调用公有成员Init()函数就可以修改了。因为Init是在类内的所以他可以访问类内的私有成员。但是不能在类外直接访问成员a。 类的两种定义方式:
1.声明和定义全部放在类体中。注意成员函数如果在类中定义编译器可能会将其当成内联函数处理。如下声明和定义全部放在类体中: class Person{
public://显示基本信息void showlnfo(){cout_name-_sex-_ageendl;}
public:char*_name;//姓名char*_sex;//性别int _age;//年龄
}; 2.类声明放在.h文件中成员函数定义放在.cpp文件中。注意成员函数名前面需要加类名::。声明放在类的头文件person.h中 class Person{
public://声明void showlnfo();
public:char*_name;//姓名char*_sex;//性别int _age;//年龄
}; 定义放在实现文件person.cpp中,在showlnfo函数名前面加了Person::表示showlnfo是Person类中的如下 #includeperson.h
//显示基本信息输出名字性别年龄
void Person::showlnfo(){cout_name-_sex-_ageendl;
}
一般情况采用第二种方式。
类的作用域类定义了一个新的作用域类的所有成员都在类的作用域中在类体外定义成员时需要使用::作用域操作符指明成员属于哪个类域。在C中{}定义的都是域。 类的实例化
用类类型创建对象的过程称为类的实例化。
类是对对象进行描述的是一个模型一样的东西限定了类有哪些成员定义处一个类并没有分配实际的内存空间来存储。一个类可以实例化多个对象实例化出的对象占用实例的物理空间存储类成员变量。
class Person{
public:void PrintPersonInfo();
private:char _name[20];char _gender[3];int _age;
};
//这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo(){cout_name _gender _ageendl;
}
若要使用Person类需要先实例化然后才能使用。
下列写法是有误的:
Person._name0; //没有创建类的变量也就是_name根本没有空间所以无法访问。
你可以这样认为类只是图纸而创建类则是根据图纸建好的房子。 封装
封装是将数据和操作数据的方法进行结合隐藏对象的实现细节仅对外公开接口来和对象进行交互。封装本质是一种管理比如电脑提供给用户仅有关开机键盘显示器..等剩下的CPU显卡都封装了。
在C中实现封装可以通过类将数据以及操作数据的方法进行结合通过访问权限来隐藏内部实现细节控制方法在类外直接被调用。
如我在类中有成员_name_age为私有的把他们隐藏起来然后再提供一个共有的void PrintPersonInfo(){}函数用来控制类内的成员然后再外调用这个函数这时这个函数就是类提供给外面的接口。 类的对象大小的计算
如类创建变量时申请了内存那么我们该如何计算类的大小如下有几种猜测:
1.对象包含类的各个成员 :缺陷:每个对象中的成员变量的值是不同的但是调用同一份相同代码的函数如果此种方式存储那么当一个类创建多个对象时每个对象都会保存一份的代码相同代码保存多次浪费空间。2.代码只保存一份再对象中保存存放代码的地址:3.只保存成员变量成员函数存放在公共的代码段:
对于上述三种方式我们可以通过不同对象分别获取大小来分析,如下: class A1{public:void f1(){}private:int _a;};//类中仅有成员函数class A2{public:void f2(){}};
// 类中什么都没有--空类class A3{};int main() {cout A1: sizeof(A1) endl;cout A2: sizeof(A2) endl;cout A3: sizeof(A3) endl;}
代码结果为sizeof(A1)4 sizeof(A2)1sizeof(A3)1。
由此可以知道一个类的大小实际就是该类中成员变量之和不是函数注意内存对齐。
注意空类的大小空类比较特殊编译器会给空类一个字节来唯一标识这个类的对象 结构体内存对齐规则 第一个成员在与结构体偏移量为0的地址处。 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处 注意对齐数编译器默认的一个对齐数 与该成员的大小较小值 VS中默认的对齐数为0 结构体总大小为最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。 如果嵌套了结构体的情况嵌套的结构体对齐到自己的最大对齐数的整数倍处结构体的整体大小就是所有最大对齐数(行嵌套结构体的对齐数)的整数倍。 类成员函数的this指针
this指针的引出
如下有一串代码
class Date {
public:void Init(int year, int month, int day){_year year;_month month;_day day;}void Print() {cout _year - _month - _day endl;}
private:int _year;int _month;int _day;
};int main() {Date d1;Date d2;Date d3;d1.Init(2023, 10, 7);d2.Init(2022, 10, 7);d1.Print();d2.Print();return 0;
}对于上述代码有这样一个问题Date类中有Init和Print两个成员函数函数体没有关于不同对象的区别那么当d1调用Init函数时该函数是如何知道应该设置d1对象而不是设置d2对象呢。
在C通过引入this解决了该问题C编译器给每个非静态的成员函数增加了一个隐藏的指针参数让该指针指向当前对象(函数运行时调用该函数的对象)在函数体中所有成员变量的操作都是通过该指针去访问只不过所有操作对用户是透明的即用户不需要来传递编译器自动完成。 如上述调用d1.Print();的代码会被编译器处理成如下代码: d1.Print();
//处理之后
d1.Print(d1);void Print(){cout _year - _month - _day endl;
}
//处理之后
void Print(Date*const this) {cout this-_year - this- _month - this- _day endl;
} 注意 this不能显示的写this相关的形参和实现。上述是编译器处理后的结果如void Print(Date*const this){} this不能作为参数但是可以在类里面显示的使用如cout this-_year - this- _month - this- _day endl; this指针的特性
this指针的类型类类型*const,即成员函数中不能该this指针赋值。只能在成员函数的内部使用。this指针的本质上是成员函数的形参当对象调用成员函数时将对象地址作为实参传递给this形参所以对象中不存储this指针。this指针是成员函数第一个隐含的指针形参一般情况由编译器通过ecx寄存器自动传递不需要用户传递。this指针在VS中是存储到栈帧上面的。this指针可以为空。