当前位置: 首页 > news >正文

C++类和对象(1)

C++类和对象(1)

  • 1.类的定义
  • 2.访问限定符
  • 3.类域
  • 4.对象的大小
  • 5.this指针

如果我想把人这个对象封装起来。
经过C语言的学习,我们可以使用结构体,里面可以定义人的种种数据。
但是如果这个人的一些数据是涉及隐私的,不想让用户知道的,该怎么办呢?
这就是今天我们学习的类与结构体的核心区别。

1.类的定义

如果是结构体,我们这样定义。

struct Date
{int _year;int _month;int _day;};

如果是类,我们这样定义。

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;//成员变量
};

class为类的关键字,后面是类名,{}中是类的主体。
类体中内容称为类的成员:类中的变量称为类的属性或成员变量,类中的函数称为类的方法或成员函数。
因为有了在成员变量前面加了private:所以我们在除了类中的所有地方都不能直接访问这个类的成员函数。
成员函数默认为inline

2.访问限定符

分为三个:public,private,protected
在现阶段的学习中我们可以暂且认为private与protected作用一样。
class定义成员时没有被访问限定符修饰时默认为private

3.类域

类定义出了一个新的作用域。在类外定义成员时,需要加上::作用域操作符指明成员属于哪个类域

class Date {
public:void Init(int year, int month, int day) {_year = year;_month = month;_day = day;}void Print();
private:int _year;int _month;int _day;
};
void Date::Print() {cout << _year << "/" << _month << '/' << _day << endl;
}

4.对象的大小

在C语言学习时,我们学习了如何判断结构体的大小与内存对齐规则。
C++也规定实例化的对象要符合内存对齐的规则。

  • 第一个成员在于结构体偏移量为0的地址处
  • 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处
  • 对齐数 =(编译器默认的一个对齐数)与(该成员大小)的较小值
  • vs中默认对齐数是8
  • 最大对齐数 =(所有变量类型最大者)与(默认对齐数)取较小
  • 结构体总大小为最大对齐数的整数倍

注意
对象中不存储成员函数,因为函数被编译后是一段指令,它们无法存储在对象中。这些指令存储在单独的区域(代码段)。

#include<iostream>
using namespace std;
// 计算⼀下A/B/C实例化的对象是多⼤? 
class A
{
public:void Print(){cout << _ch << endl;}
private:char _ch;int _i;
};
class B
{
public:void Print(){//...}
};
class C
{
};
int main()
{A a;B b;C c;cout << sizeof(a) << endl;cout << sizeof(b) << endl;cout << sizeof(c) << endl;return 0;
}

在这里插入图片描述

为什么b和c的大小是1呢?完全是因为要代表这个对象存在,不得不分配一个字节来说明其存在。

5.this指针

以上面的Date类为例,当我们创建了两个对象的d1.d2并调用成员函数时,该函数是如何知道应该访问d1还是d2呢?
编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this指针。比如Date类的Init的真实原型:
void Init ( Date* const this, int year, int month, int day )

  • 类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给_year赋值, this->_year = year;
  • C++规定不能在实参和形参的位置显⽰的写this指针(编译时编译器会处理),但是可以在函数体内显示使用this指针。

所以其实void Init( int year, int month, int day)就等价于
void Init(Date* const this, int year, int month, int day)

接下来是两道经典例题

#include<iostream>
using namespace std;
class A
{
public:void Print(){cout << "A::Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}

A.编译报错 B.运行崩溃 C.正常运行
注意:
当指针指向的内容是对象时,用它调用类中变量和函数的本质(类似p->Print())是将自己传给this指针。并非真正的解引用。
当我们调试转到反汇编时:
在这里插入图片描述
所以p->Print();实际上并没有发生解引用这一步,自然不会报错。
所以选C

#include<iostream>
using namespace std;
class A
{
public:void Print(){cout << "A::Print()" << endl;cout<<_a<<endl;}
private:int _a;
};
int main()
{A* p =nullptr;p->Print();return 0;
}

A.编译报错 B.运行崩溃 C.正常运行
在这里插入图片描述
在Print函数中,_a就是this->_a,而p指针是空指针,所以this也是空指针,所以会运行错误。

如有错误,欢迎打在评论区。
主页还有更多优质内容OvO

http://www.dtcms.com/a/436041.html

相关文章:

  • 嵌入式开发学习日志32——stm32之PWM
  • 数据结构 之 【图的最短路径】(Dijstra、BellmanFord、FloydWarShall算法实现)
  • 时序数据库高基数问题(一):当数据标签太多时会发生什么
  • 东莞市企业网站制作企业关键词推广优化排名品牌
  • 个人网站免费搭建软文标题和内容
  • 普洱高端网站建设价格燕郊房价2023年最新房价走势
  • 怎么做二维码微信扫后直到网站合肥网站排名提升
  • 如何办网站 论坛网站一定要公司吗
  • 主流网站开发平台新媒体运营需要哪些技能
  • 江门网站php网站开发遇到的问题
  • 做韦恩图网站建网站如果不买域名别人能不能访问
  • 如何让订阅号菜单做微网站安徽鲁班建设集团网站
  • 51——DS18B20
  • 网站建设安全协议wordpress 添加插件
  • 区总工会加强网站意识形态建设深圳网络科技有限公司简介
  • 【HTB】Season9 Imagery Walkthrough
  • 异常与c++11中的noexcept【c++】
  • 免费网站制作效果重庆建设施工安全信息网官网
  • 网站设计报价是多少钱网站建设项目计划书
  • Python语言中的应用程序接口(API):本质探析、高级应用与实践范式
  • 小学生做网站下载谷歌浏览器
  • 淄博网站制作高端营销手表网站妨水
  • Spring Boot 常用注解分类整理(含用法示例)
  • 运动网站设计江西商城网站建设
  • 如何做关于网站推广的培训公众号软文怎么写
  • Spring Boot 配置详解:从引导器到注解实战(初学者指南)
  • 网站建设的结论和体会苏州高端建站公司
  • 珠海建设局网站查公司业绩专业h5网站建设教程
  • 136、【OS】【Nuttx】【周边】效果呈现方案解析:strace 日志解析(二)
  • 呼市做网站建设的公司哪家好一个网站成本