响应式网站建设哪里有海外域名商
响应式网站建设哪里有,海外域名商,禾天姿网站开发,外贸业务推广目录
1、前言
2、类的引入
3、类的定义
3.1 类的两种定义方式
4、类的访问限定符
5、类的作用域
6、类的实例化
7、类对象模型
7.1 内存对齐规则
7.1 类对象的存储方式
8、this指针
8.1 this指针的特性
8.2 this指针是否可以为空 1、前言 C语言是面向过程的#…目录
1、前言
2、类的引入
3、类的定义
3.1 类的两种定义方式
4、类的访问限定符
5、类的作用域
6、类的实例化
7、类对象模型
7.1 内存对齐规则
7.1 类对象的存储方式
8、this指针
8.1 this指针的特性
8.2 this指针是否可以为空 1、前言 C语言是面向过程的关注的是过程分析出求解问题的步骤通过函数调用逐步解决问题。 C是基于面向对象的关注的是对象将一件事情拆分成不同的对象靠对象之间的交互完成。 我们来举列子说明一下
比如蒸米饭这件事C语言关注的就是淘米 - 加水 - 加米 - 起锅 - 烧锅 - 水沸腾 - 放入盛有生米的盆 - 烧锅 - 拿出C在这里关注的是对象人、米、水、电饭煲人不需要知道电饭煲如果工作的只需要四个对象之间交互完成任务就可以。
2、类的引入 C语言结构体(struct)中只能定义变量。 而在C中新增加了玩法结构体内不仅可以定义变量也可以定义函数。 举例
struct Person
{void personInit(){cout void personInit() endl;}int _age;char _name[20];
};
int main()
{Person p;p.personInit();return 0;
}
上面结构体的定义在C中更喜欢用class来代替。
3、类的定义
class className
{
// 类体由成员函数和成员变量组成
}; // 一定要注意后面的分号 class为定义类的关键字ClassName为类的名字{}中为类的主体注意类定义结束时后面分号不能省略。 类体中内容称为类的成员类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。 3.1 类的两种定义方式
3.1.1 声明和定义全部放在类体中
需注意成员函数如果在类中定义编译器可能会将其当成内联函数处理。
class Person
{
public:void PersonInit(){cout void PersonInit() endl;}private:int _age;char _name[20];
};
3.1.2 类声明放在.h文件中成员函数定义放在.cpp文件中 注意成员函数名前需要加类名::
//Person.h
class Person
{
public:void PersonInit();private:int _age;char _name[20];
};//Person.c
#include Person.h
void Person::PersonInit()
{cout void Person::PersonInit() endl;
}
一般情况下更期望采用第二种方式。
注意一般在声明成员变量的时候成员变量前加_下划线为区分成员函数的形参只要能区分就可以前家下划线是我的一种方式谷歌C规范一般喜欢后加_。
如果成员变量没有特殊标记时当在成员函数内用到成员变量并为其赋值的时候函数会采用局部优先的原理将自己赋给自己这样就达不到预期的效果。
4、类的访问限定符
C实现封装的方式用类将对象的属性与方法结合在一块让对象更加完善通过访问权限选择性的将其接口提供给外部的用户使用。 【访问限定符说明】 1. public修饰的成员在类外可以直接被访问 2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的) 3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止 4. 如果后面没有访问限定符作用域就到 } 即类结束 5. class的默认访问权限为privatestruct为public(因为struct要兼容C)。注意访问限定符只在编译时有用当数据映射到内存后没有任何访问限定符上的区别。 5、类的作用域
类定义了一个新的作用域类的所有成员都在类的作用域中。在类体外定义成员时需要使用 :: 作用域操作符指明成员属于哪个类域。 例如
class Person
{
public:void PersonInit();//声明private:int _age;char _name[20];
};//初始化定义的时候函数名前加 Person::表明PersonInit是Person类域的
void Person::PersonInit()//定义
{cout void Person::PersonInit() endl;
}
6、类的实例化
用类类型创建对象的过程称为类的实例化。
在实例化之前定义出来的类是不占空间的。 例如
class Person
{
public:void PersonInit(){cout void PersonInit() endl;}private:int _age; //声明char _name[20];
};int main()
{Person::_age 20;//定义开空间Person p;return 0;
}
在没有实例化p的时候定义的 class Person 类不会开辟空间。 实例化出了 p 对象这时 p 是占用实际的空间的存储了成员变量。这里实例化后p也不能直接用_age因为是私有的后面会讲如何赋值打印。 类就像是设计图。 类实例化出对象就像现实中使用设计图盖房子。 在没有盖房子之前这块区域没有占空间。 实例化就是按图盖房子这时就占用了空间。 我们可以使用设计图盖多个房子这些房子都占空间 7、类对象模型
如何计算类对象的大小呢
例如
class A
{
public:void AInit(int a, int b){cout void AInit(int a, int b) endl;}private:int _a;int _b;
};
class B
{private:int _a;int _b;
};
class C
{};
int main()
{cout 类A的大小 sizeof(A) endl;cout 类B的大小 sizeof(B) endl;cout 类C的大小 sizeof(C) endl;return 0;
}
运行结果 总结 1、成员函数不算在类的大小中 2、类的大小只与成员变量有关并遵循结构体对齐规则 3、空类的大小为1字节不存储数据只是占位表示对象存在过。 7.1 内存对齐规则 1. 第一个成员在与结构体偏移量为0的地址处。 2. 其他成员变量要对齐到某个数字对齐数的整数倍的地址处。 注意对齐数 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的对齐数为8 3. 结构体总大小为最大对齐数所有变量类型最大者与默认对齐参数取最小的整数倍。 4. 如果嵌套了结构体的情况嵌套的结构体对齐到自己的最大对齐数的整数倍处结构体的整 体大小就是所有最大对齐数含嵌套结构体的对齐数的整数倍。 7.1 类对象的存储方式
为什么类中的成员函数不占空间那成员函数是存在哪里呢
实例化后的类中只存储类成员变量
成员函数保存在公共的代码段。
我们画图来理解一下 8、this指针
我们这里写一个日期类来看一下
class Date
{
public:void Init(int year, int month, int day){_year year;_month month;_day day;}private:int _year;int _month;int _day;
};int main()
{Date d1;d1.Init(2023, 7, 30);return 0;
}
这里看似 Init 函数只有三个形参
调用的时候传了三个参数
实际上这里还隐含了一个 this 指针。
我们这里画图来看一下 这里对成员变量赋值的时候前后都会加一个 this- 来接引用访问。 8.1 this指针的特性 1. this指针的类型类类型* const即成员函数中不能给this指针赋值。 2. 只能在“成员函数”的内部使用。 3. this指针本质上是“成员函数”的形参当对象调用成员函数时将对象地址作为实参传递给this形参。所以对象中不存储this指针。 4. this指针是“成员函数”第一个隐含的指针形参一般情况由编译器通过ecx寄存器自动传递不需要用户传递。 因此我们写的时候就不可以这样写
class Date
{
public:void Init(Date* this, int year, int month, int day){_year year;_month month;_day day;}private:int _year;int _month;int _day;
};int main()
{Date d1;d1.Init(d1, 2023, 7, 30);return 0;
} this指针隐含着如果我们自己加上就是错误的。
this在实参和形参的位置上不能显示写
但是在类里面可以显示的用
如下
class Date
{
public://this在实参和形参的位置上不能显示写//但是在类里面可以显示的用void Init(int year, int month, int day){this-_year year;this-_month month;this-_day day;}private:int _year;int _month;int _day;
};int main()
{Date d1;d1.Init(2023, 7, 30);return 0;
}
8.2 this指针是否可以为空
我们来看下面几段代码
class Person
{
public:void PersonInit(){cout void PersonInit() endl;}private:int _age; //声明char _name[20];
};int main()
{Person* p nullptr; //初始化为空指针p-PersonInit();return 0;
}
运行结果 这里我们就会产生疑问p是空指针为什么可以解引用呢还是正常运行。
这里对于函数定义在类里面且短小编译器会当作内联函数直接展开并不会解引用
而如果声明与定义分离或者编译器不将其当作内联函数就是call Init函数调用函数的地址也不是解引用。
我们继续看
class Person
{
public:void PersonInit(){cout void PersonInit() endl;}//private:int _age; //声明char _name[20];
};int main()
{Person* p nullptr; //初始化为空指针p-PersonInit();p-_age 1;return 0;
}
这就会导致运行崩溃对空指针的内容进行解引用。 我们接着上面看
class Person
{
public:void PersonInit(){cout _age endl;}//private:int _age; //声明char _name[20];
};int main()
{Person* p nullptr; //初始化为空指针p-PersonInit();return 0;
}
这里在调用Init函数的时候函数里面产生了解引用但是this是空指针这里就会运行崩溃。 空指针不会编译错误只会导致运行崩溃。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/86686.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!