【C++】类与对象上

2023-11-10


在这里插入图片描述

1.auto关键字

1.1auto介绍

C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

#include<iostream>
using namespace std;
int test()
{
	return 1;
}
int main()
{
	int a = 10;
	auto b = a;
	auto c = 'a';
	auto d = test();
	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	cout << typeid(d).name() << endl;
	return 0;
}

image-20220511233857696

注意:因为auto是根据赋值对象推断,所以auto修饰的变量必须要初始化。在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”, 在编译阶段,编译器会对auto替换为推断出的类型。

1.2auto使用规则

auto与指针和引用结合使用。

**用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加& **

int main()
{
	int x = 10;
	auto a = &x;
	auto* b = &x;
	auto& c = x;
	cout << typeid(a).name() << endl;
	cout << typeid(b).name()<< endl;
	cout << typeid(c).name() << endl;
	return 0;
}

image-20220511235207314

同一行定义多个变量

auto a=10,b=20; //auto先根据a的类型推断出为int类型,而b=20也是int类型所以可以编译通过。
auto c=10,d=4.0 //编译无法通过;因为auto在编译过程是被替换
1.3auto不能推导的情况

1.auto不能作为函数的参数

void test(auto a)
{
    
}

2.auto不能作为函数的返回类型

auto test(int a)
{
    return 10;
}

3.auto不能直接用来声明数组

void test()
{
    int a[]={1,2,3};
    auto b[]={4,5,6}
}
1.4范围for循环
//一般的写法
void test1()
{
    int array[]={1,2,3,4,5,6,7,8,9};
    int len=sizeof(array)/sizeof(array[0]);
    for(int i=0;i<len;i++)
    {
        array[i]*=2;
    }
    for(int i=0;i<len;i++)
    {
        cout<<array[i]<<" ";
    }
    cout<<endl;
}

范围for循环

void test1()
{
    int array[]={1,2,3,4,5,6,7,8,9};
    for(auto a:array)
    {
        a*=2;
    }
    for(auto a:array)
    {
        cout<<a<<" ";
    }
    cout<<endl;
}

image-20220512001202663

这里的a只是array[i]的临时拷贝。因此改变a无法改变array的值;

如果想要对array的值进行修改,只需要把a修改为引用。

void test1()
{
    int array[]={1,2,3,4,5,6,7,8,9};
    for(auto& a:array)
    {
        a*=2;
    }
    for(auto a:array)
    {
        cout<<a<<" ";
    }
    cout<<endl;
}

image-20220512001710734

范围for循环的使用条件:for循环迭代的范围必须是确定的

对于数组来说,范围是数组第一个元素和最后一个元素的范围。而对于可迭代的类而言,begin和end就是for循环迭代的范围

void testfor(int array[])
{
    for(auto& a:array)
        cout<<a<<endl;
}
//编译无法通过

在这里插入图片描述

2.指针空值nullptr

nullptr是c++11新增加的关键字

头文件中NULL的定义

#ifndef NULL
    #ifdef __cplusplus
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif
#endif

从上面的文件可以看出,在CPP中NULL就是字面常量0;

在C语言中,NULL被定义为无类型指针(void*)的常量

void f(int)
{
	cout <<"f(int)" << endl;
}
void f(int*)
{
	cout << "f(int*)" << endl;
}
int main()
{
	f(0);
	f(NULL);
	f((int*)0);
	f((int*)NULL);
	return 0;
}

image-20220512004004577

总结:在c++中,指针的初始化尽量使用nullptr
在这里插入图片描述

3.类与对象

C++与C语言不同,C语言是面向过程的语言,关注的是过程,分析出求解问题的步骤

C++是基于面向对象语言,关注的是对象,将一件事情拆为不同的对象,靠对象之间的交互完成

3.1类

C语言中,结构体只能够定义变量,C++中结构体不仅可以定义变量还能够定义函数

struct MyStruct
{
	void init(const char*name,const int age,const char*sex,const int id)
	{
		_age = age;
		strcpy(_name, name);
		strcpy(_sex, sex);
		_id = id;
	}
	void print()
	{
		cout << _name << " " << _age << " " << _sex << " " << " _id" << endl;
	}
	char _name[20];
	int _age;
	char _sex[10];
	int _id;
};

int main()
{
	MyStruct s;
	s.init("张三", 18, "男", 11111);
	s.print();
	return 0;
}

image-20220512005539329

3.2类的定义

C++中常常使用关键字class定义类;为了兼容C语言,也可以使用struct定义类;但是两者在细节上有些不同,后面会进行介绍。

class student
{
public:
	void init(const char*name,const int age,const char*sex,const int id)
	{
		_age = age;
		strcpy(_name, name);
		strcpy(_sex, sex);
		_id = id;
	}
	void print()
	{
		cout << _name << " " << _age << " " << _sex << " " << " _id" << endl;
	}
public:
	char*_name;
	int _age;
	char*_sex;
	int _id;
};

int main()
{
	student s;
	s.init("张三", 18, "男", 11111);
	s.print();
	return 0;
}
3.3类的访问限定符和封装

访问限定符:public(公有),protected(保护),private(私有)

访问限定符的权限是针对类内部和类外部来区分的

  • public修饰的成员在类外可以直接被访问
  • protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
  • 访问权限**作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
  • class的默认访问权限为private,struct为public(因为struct要兼容C)
class student
{
public:
	void init(const char*name,const int age,const char*sex,const int id)
	{
		_age = age;
		strcpy(_name, name);
		strcpy(_sex, sex);
		_id = id;
	}
	void print()
	{
		cout << _name << " " << _age << " " << _sex << " " << " _id" << endl;
	}
private:
	char*_name;
	int _age;
	char*_sex;
	int _id;
};

int main()
{
	student s;
	s.init("张三", 18, "男", 11111);
	s.print();
    cout<<s._name<<endl;
	return 0;
}
//编译报错:
//student::_name”: 无法访问 private 成员(在“student”类中声明)
3.4封装

面向对象有三大特征:封装继承多态

封装:本质上是一种管理数据和操作数据的一种思想。将数据和操作数据的方法有机结合,隐藏对象的属性和实现的细节,仅对外公开接口与对象进行交互。

3.4类的作用域

定义一个类就定义了一个新的作用域,因此需要在类外使用成员变量时,需要指明成员属于的类域。

class student
{
public:
	int age;
	int id;
};
class teacher
{
public:
	int age;
	int id;
};
3.5类对象模型
class tmp
{
public:
	void init(int age, char* name, int id)
	{
		_age= age;
		strcpy(_name, name);
		_id = id;
	}
	void print()
	{
		cout << _age << " " << _name << " " << _id << endl;
	}
private:
	int _age;
	char _name[20];
	int _id;
};

tmp类型实例化后大小是多少?

int main()
{
	tmp t;
	t.init(18,"张三",1111);
	cout << sizeof(t) << endl;
	return 0;
}

image-20220512012910262

输出结果为28

struct tmp
{
	int _age;
	char _name[20];
	int _id;
};
int main()
{
	tmp t = { 18,"张三",11111 };
	cout << sizeof(t) << endl;
	return 0;
}

image-20220512013252578

说明成员函数并没有在对象中占用空间,因此可以推断出类对象的存储方式。

image-20220512013441897

从汇编代码验证

class tmp
{
public:
	void init(int age, const char* name, int id)
	{
		_age= age;
		strcpy(_name, name);
		_id = id;
	}
	void print()
	{
		cout << _age << " " << _name << " " << _id << endl;
	}
private:
	int _age;
	char _name[20];
	int _id;
};

int main()
{
	tmp t;
	t.init(18,"张三",1111);
	t.init(19, "李四", 2222);
	return 0;
}

image-20220512013733908

两个对象调用的是同一地址的函数

3.6类的大小和内存对齐
class A1 
{
public:
	void f1() {}
private:
	int _a;
};
// 类中仅有成员函数
class A2 
{
public:
	void f2() {}
};
// 类中什么都没有---空类
class A3
{};
int main()
{
	cout << sizeof(A1) << " " << sizeof(A2) << " " << sizeof(A3) << endl;
	return 0;
}

image-20220512014107729

**结论:**当类对象只有成员函数据或者什么也没有时,类对象的大小为1字节

内存对齐的规则

  • 第一个成员在与结构体偏移量为0的地址处。
  • 其他成员变量要对齐到对齐数的整数倍的地址处。
  • 注意:对齐数 =编译器默认的一个对齐数 与 该成员大小的较小值。VS中默认的对齐数为8
  • 结构体总大小为:最大对齐数(所有变量类型对齐数最大者与默认对齐参数取小)的整数倍。
  • 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++】类与对象上 的相关文章

随机推荐

  • 数字电路经验贴

    1 有时候会写一些通用模块 但是在实际使用的时候 模块内部的功能不会全部用到 会导致覆盖率上不去 以及面积增大 后续工作可以考虑怎么避免这种情况
  • ubuntu系统空间占满,无法启动

    1 今天第一次遇到Ubuntu系统整个崩溃无法启动 这个时候会出现下图所示 2 此时重启 选择recovery模式 进行修复 如下图所示 小白的我不懂以为只要进行了第二项的清处就可以 亲自尝试只清理出空间80M 3 此时应该选择root 选
  • 【机器人仿真Webots教程】-Webots安装

    Webots安装 文章目录 Webots安装 1 Webots简介 2 Webots安装 2 1 系统要求 2 2 验证显卡驱动 2 3 安装 3 Webots仿真 3 1 world文件 3 2 Controller文件 3 3 Supe
  • “全国首款自主研发IDE”——CEC-IDE(VSCode)

    省流 开源的钱真好赚 本人没有多好的文笔直接放图 从 芯 出发 前端时间用 芯 做营销的还是一个无脑恋爱剧 我的中国 芯 现在打着爱国旗号的钱就那么好圈了吗 然后就是软件上图为微软开发开源的代码编辑器下图为所谓国产自研的IDE 不能说是毫不
  • jqgrid jsonReader

    jsonReader root data page page total total records record repeatitems false 1 json 是一个比较好web 传送数据格式 jqgrid里面jsonreader 怎
  • 学习笔记-Matlab算法篇-时间序列

    时间序列 01时间序列模型 介绍 时间序列是按时间顺序排列的 随时间变化且相互关联的数据序列 分析时间序列的方法构成数据分析的一个重要领域 即时间序列分析 时间序列根据所研究的依据不同 可有不同的分类 1 按所研究的对象的多少分 有一元时间
  • uniapp的picker标签实现多级联动

  • C语言中#if的使用

    if定义 if和 endif是一组同时使用的 叫做条件编译指令 if与 define include等指令一样是由预处理器这个强大的工具处理的 预处理器可以在编译前处理c程序 if使用 if的后面接的是表达式 if MAX 10 MAX 2
  • filezilla如何连接远程FTP服务器

    进入站点管理 创建站点 填写对应连接信息 端口默认不写就是21
  • c语言编程代码五星红旗,飘动的五星红旗

    程序清单 include graphics h include stdlib h void main int size int driver VGA int mode VGAHI int d 60 40 60 65 65 40 50 65
  • 平衡车之mpu6050调试及问题总结

    这里重点讲解AD0的作用 I2C通讯中从机是要有地址的 以区别多个从机 当AD0管脚接低电平的时候 从机地址是0x68 从MPU6050的寄存器中我们可以得到答案 MPU6050作为一个IIC从机设备的时候 有8位地址 高7位的地址是固定的
  • java.lang.NumberFormatException for input string “1“异常处理

    首先说下这个异常出现原因 这个异常是因为csv编码为utf 8导致的 改成就ANSI好了 然后再说明一下异常出现场景 读取csv文件 gt 转成json数据 gt 再转成对象 这个异常是在json数据转成对象时出现了 JSONObject
  • Struts2基础学习总结

    Struts 2是在WebWork2基础发展而来的 注意 struts 2和struts 1在代码风格上几乎不一样 Struts 2 相比Struts 1的优点 1 在软件设计上Struts 2 没有像Struts 1那样跟Servlet
  • C语言基础入门48篇_42_共用体(关键字union,共用体占用大小为成员中最大值、结构体为所有成员相加,所占内存比单纯相加大)

    1 共用体的定义与使用 共用体的关键字是 union 共用体是非基本数据类型 同结构体类似 我们需要先声明共用体类型 再利用自定义的类型去定义变量 include
  • 揭秘国产操作系统的黄金测试利器:探索开源测试工具的神秘世界

    揭秘国产操作系统的黄金测试利器 探索开源测试工具的神秘世界 文章目录 1 前言 2 国产操作系统现状的深度解析 3 国产操作系统的质量保障神器 开源测试工具 4 开源测试工具的重要性 5 国产操作系统如何利用开源测试工具进行黄金测试 6 国
  • 什么是子系统、模块、功能点,你清楚吗?

    1 子系统 对于所实现系统在功能上做的整体划分 可以是某个子系统 2 功能模块 子系统下的功能点的集合 3 功能点 通过用户交互触发 外部系统触发或后台程序触发来完成的一个完整的动作 搞清楚这些 有助于你书写建设方案 设计文档
  • Java--IDEA中Spring配置错误:class path resource [.xml] cannot be opened because it does not exist

    一 报错 运行 Spring 项目时报错如下 class path resource beans xml cannot be opened because it does not exist 没有找到 beans xml 配置文件 二 报错
  • 爬取旅游网站

    完整代码如下 可直接copy from bs4 import BeautifulSoup import urllib request import sqlite3 import os import time import threading
  • Maven项目里的pom解析和nexus私服

    一 什么是pom POM 即Project Object Model 通过pom xml文件配置Maven2 然后Maven2根据此配置执行 作用类似ant的build xml文件 功能更强大 该文件用于管理 源代码 配置文件 开发者的信息
  • 【C++】类与对象上

    文章目录 1 auto关键字 1 1auto介绍 1 2auto使用规则 1 3auto不能推导的情况 1 4范围for循环 2 指针空值nullptr 3 类与对象 3 1类 3 2类的定义 3 3类的访问限定符和封装 3 4封装 3 4