cpp_03_引用_类型转换_温和强转_面向对象

1  引用的应用

1.1  数据传递--值传递

        C语言只要涉及数据传递(例如:初始化、赋值、传参、返回值),

        都为值传递(将数据复制一份给到目标内存)。

// value.cpp 值传递:将数据复制一份给别人
#include <iostream>
using namespace std;void foo( int x ) {  }int bar( ) {int m = 8888;return m;
}int main( void ) {int a = 10; // 初始化a = 20; // 赋值foo( a ); // 传参/*|8888|*/bar( ); // 返回值return 0;
}

        C++语言因为有引用,可以不做值传递。 

        1)引用型形参:函数的形参是实参的别名,避免对象复制的开销。

                非常引用型参数,可在函数中修改实参值;

                引用型参数,防止了对实参的意外修改,  也接受常量型实参(右值)。

// vparam.cpp 引用 作为函数的 形参
// 当我们在设计一个函数时,只要可以确定在函数内部绝对不修改实参,那么大胆的加上const
#include <iostream>
using namespace std;void Swap( int* x, int* y ) { // int z = *x;*x = *y;*y = z;
}void Swap( int& x, int& y ) { // 非常引用型 形参:函数内部可以直接修改实参int z = x;x = y;y = z;
}
void Printer( const int& x, const int& y ) { // 常引用型 形参:能够防止意外修改实参
//  x = 888; // 编译器会提醒我们read-only  (打印机就应该原样打印哦)cout << x << ' ' << y << endl;
}int main( void ) {int a=10, b=20;Swap( a, b );
//  Swap( &a, &b ); // 这种写法并不直观cout << "a=" << a << ", b=" << b << endl;Print( a, b );Print( 888, 999 ); //接受常亮型实参(右值)return 0;
}

         2)引用型的返回值:从函数中返回引用,一定要保证函数返回后,该引用的目标依然有效

                        -可以返回全局静态变量的引用

                        -可以返回在中动态创建(new)的对象的引用

                        -可以返回引用型参数本身

                        -可以返回成员变量的引用 

                        -可以返回调用对象自身的引用 

                        -不能返回局部变量的引用

               非常引用型返回值:通过引用可以修改目标

               引用型返回值:通过引用不能修改目标

// vreturn.cpp 引用 作为函数的 返回值
#include <iostream>
using namespace std;
int g_value = 0;
int& foo() { // 非常引用型 返回值:可以通过引用修改目标return g_value;
}
const int& fooo() { // 常引用型 返回值:不可以通过引用修改目标return g_value;
}int& bar() {static int s_value=0;//这行代码是在程序启动时就执行,而且只执行1次,不是每次调bar都执行cout << "s_value=" << s_value << endl;return s_value;
}int& hum() {int* p = new int;return *p;
}int& fun( int& x ) {// ...return x; // 返回 引用型 参数本身
}
/*
int& boo() {int m = 666;return m; // 不要返回局部变量的引用
}
*/
int main( void ) {foo() = 100;cout << "g_value=" << g_value << endl;//    fooo() = 888; // readonly - errorbar() = 200;bar();hum() = 300;int a_value = 0;fun(a_value) = 400;cout << "a_value=" << a_value << endl;//  boo();return 0;
}

        在实现(汇编)层面,引用就是指针,但在C++语言层面,引用不是实体类型,由此推导出,C++语言层面,引用与指针存在明显的差别:

        1)指针可以不初始化,其目标可在初始化后随意变更(指针常量除外),

              引用必须初始化,且一旦初始化就无法变更其目标。

        2)存在空指针,不存在空引用

        3)存在指向指针的指针,不存在引用的引用

        4)存在指针的引用,不存在引用的指针

        5)存在指针数组,不存在引用数组,但存在数组引用。

// poi_ref 指针 和 引用 的差别
#include <iostream>
using namespace std;int main( void ) {int a=10, b=20;int* pa = &a; // 指针可以不做初始化,也可以做初始化pa = &b; // 指针可以随意变更它所指向的目标内存int& ra = a; // 引用必须初始化ra = b; // 引用不可以随意变更它所代表的目标内存( ra仍然是a的别名 )pa = NULL; // 存在空指针
//  ra = NULL; // 不存在空引用int** ppa = &pa; // 存在二级指针
//  int&& rra = ra;  // 不存在二级引用int* &rpa = pa; // 存在指针的引用  !!
//  int& *pra = &ra; // 不存在引用的指针int* p = &ra; // 这里取的并不是引用本身的地址,而是引用的目标内存a的地址int x, y, z;int*parr[3] = {&x, &y, &z}; // 存在指针的数组
//  int&rarr[3] = {x,y,z}; // 不存在引用的数组int arr[3];int(&rr)[3] = arr; // 存在数组的引用return 0;
}

 

2  显示类型转换(强转)

        C风格的显示类型转换:        (int)a 

        C++风格的显示类型转换:    int(a) 

// convert_pre.cpp 显式(强制)类型转换
#include <iostream>
using namespace std;int main( void ) {int a;  double b;   float c;    short d;    char e;// 任何基本类型变量之间都可以 隐式转换a = b = c = d = e;e = d = c = b = a;// 任何其他类型的指针 到 void* 都可以隐式转换void* pv = &a;pv = &b;pv = &c;pv = &d;pv = &e;// void* 到 任何其他类型的指针 都必须强转(显式转换)int* pa = (int*)(pv);double* pb = (double*)(pv);float* pc = (float*)(pv);short* pd = (short*)(pv);char* pe = (char*)(pv);// 任何类型的 非常指针 到 同类型的常指针 都可以隐式转换const int* cpa = pa;const double* cpb = pb;const float* cpc = pc;const short* cpd = pd;const char* cpe = pe;// 任何类型的 常指针 到 同类型非常指针 都必须强转pa = (int*)(cpa);pb = (double*)(cpb);pc = (float*)(cpc);pd = (short*)(cpd);pe = (char*)(cpe);return 0;
}

3  温和强转

3.1  静态类型转换

                static_cast<目标类型>(源类型变量)

                隐式类型转换的逆转换(去常除外)

                自定义类型转换 

3.2  动态类型转换 

                dynamic_cast<目标类型>(源类型变量) 

                多态父子类指针或引用之间的转换 

3.3  常类型转换

                const_cast<目标类型>(源类型变量)

                去除指针或引用上的const属性

3.4  重解释类型转换

                reinterpret_cast<目标类型>(源类型变量)

                任意类型的指针之间的转换

                任意类型的引用之间的转换

                任意类型的指针和整型之间的转换

// convert.cpp 显式(强制)类型转换
#include <iostream>
using namespace std;int main( void ) {int a;  double b;   float c;    short d;    char e;// 任何基本类型变量之间都可以 隐式转换a = b = c = d = e;e = d = c = b = a;// 任何其他类型的指针 到 void* 都可以隐式转换void* pv = &a; // int*->void*pv = &b;pv = &c;pv = &d;pv = &e;// void* 到 任何其他类型的指针 都必须强转(显式转换)*************int* pa = static_cast<int*>(pv); // void*->int*的反向int*->void*可以隐式double* pb = static_cast<double*>(pv);float* pc = static_cast<float*>(pv);short* pd = static_cast<short*>(pv);char* pe = static_cast<char*>(pv);// 任何类型的 非常指针 到 同类型的常指针 都可以隐式转换const int* cpa = pa; // int*-->const int*const double* cpb = pb;const float* cpc = pc;const short* cpd = pd;const char* cpe = pe;// 任何类型的 常指针 到 同类型非常指针 都必须强转***************pa = const_cast<int*>(cpa); // 去常属性pb = const_cast<double*>(cpb);pc = const_cast<float*>(cpc);pd = const_cast<short*>(cpd);pe = const_cast<char*>(cpe);// 除了void*外,其他任何类型的指针之间都必须强转*************pa = reinterpret_cast<int*>(pb); // double*-->int*pb = reinterpret_cast<double*>(1000); // int-->double*return 0;
}

 

4  面向对象

4.1  what

        一切皆对象。

        把大型软件看成是由多个对象组成的团推。

        对象拥有足够的智能,能够理解来自其他对象的信息,并以适当的行为作出反应。

        面向对象的三大特征:封装、继承、多态。

4.2  why

        相比分而治之的结构化程序设计,强调大处着眼的面向对象程序设计思想,更适合开发大型软件。

        得益于代码复用等面向对象的固有特征,软件开发的效率获得极大提升,成本却大幅降低。

4.3  how

        至少掌握一种面向对象的程序设计语言,如C++

        深入理解封装、继承、多态等面向对象的重要概念

        学习设计模式,源自多年成功经验的积累总结。

第三个错误:等号右边是右值,故等号左边应为万能引用int* const &r :

//test.cpp
#include <iostream>
using namespace std;int main( void ) {int arr[9] = {9,3,1,4,2,7,5,8,6};int* p = arr;       // 正确  &arr[0]int(*pp)[9] = &arr; // 正确//  int* &r = arr;      // 错误 &arr[0]     int* const& r = arr;// 正确int(&rr)[9] = arr;  // 正确
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/229410.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Diva配置——Communication Tests

关联文章:CANoe.Diva生成测试用例 Diva目录 一、CANoe.Diva简介二、Communication Tests配置一、CANoe.Diva简介 CANoe.DiVa 是一种 CANoe 选项,用于对 ECU 中的诊断软件实施进行自动化测试。 可以通过CANdelaStudio制作的CDD或ODX文件,经过Diva配置自动生成测试用例和测试脚…

【日积月累】Mysql性能优化

目录 【日积月累】Mysql性能优化 1.前言2.MySql性能优化的主要方面2.1硬件和操作系统成面优化2.2架构设计层优化&#xff08;表结构&#xff09;2.3程序配置优化2.5表结构及索引优化2.4sql执行优化 3.总结4.参考 文章所属专区 积月累 1.前言 MySQL是一种常用的开源关系型数据…

ACL原理和配置

一.ACL概述 1.介绍 ACL 访问控制列表&#xff0c;可以通过对网络中报文流的精确识别&#xff0c;与其他技术结合&#xff0c;达到控制网络访问行为、防止网络攻击和提高网络带宽利用率的目的&#xff0c;从而切实保障网络环境的安全性和网络服务质量的可靠性。 2.概述 ACL是…

ShenYu网关注册中心之Zookeeper注册原理

文章目录 1、客户端注册流程1.1、读取配置1.1.1、用于注册的 ZookeeperClientRegisterRepository1.1.2、用于扫描构建 元数据 和 URI 的 SpringMvcClientEventListener 1.2、扫描注解&#xff0c;注册元数据和URI1.2.1、构建URI并写入Disruptor1.2.2、构建元数据并写入Disrupto…

[C语言]大小端及整形输出问题

假设在一个32位little endian 的机器上运行下面的程序&#xff0c;结果是多少 ? 1.1先看以下三个程序 #include <stdio.h> int main() {long long a 1, b 2, c 3;printf("%lld %lld %lld\n", a, b, c); // 1 2 3printf("%d %d %d %d %d %d\n&quo…

Learning Semantic-Aware Knowledge Guidance forLow-Light Image Enhancement

微光图像增强&#xff08;LLIE&#xff09;研究如何提高照明并生成正常光图像。现有的大多数方法都是通过全局和统一的方式来改善低光图像&#xff0c;而不考虑不同区域的语义信息。如果没有语义先验&#xff0c;网络可能很容易偏离区域的原始颜色。为了解决这个问题&#xff0…

c语言-全局变量与局部变量

目录 1、&#xff08;作用&#xff09;域的概念 2、全局与局部的相对性 3、生命周期 3、静态变量static 结语&#xff1a; 前言&#xff1a; 在c语言中&#xff0c;全局变量的可见范围是整个工程&#xff0c;而局部变量的可见范围从该变量被定义到该作用域结束&#xff0c…

【JavaEE】多线程(5) -- 阻塞队列

目录 1.阻塞队列是什么? 2.生产者消费者模型 3.标准库中的阻塞队列 4.阻塞队列的实现 1.阻塞队列是什么? 阻塞队列是⼀种特殊的队列. 也遵守 "先进先出" 的原则 阻塞队列能是⼀种线程安全的数据结构, 并且具有以下特性: 当队列满的时候, 继续⼊队列就会阻塞, …

I/O流的相关内容

首先我们了解一下什么是文件&#xff1a; 文件其实就是让我们用来保存数据的地方&#xff0c;它可以用来保存信息&#xff0c;图片&#xff0c;以及音频等各类数据。 文件流&#xff1a; 那我们是如何通过我们的程序来进行对文件的操作呢&#xff1f;这里我们就要提出一个概…

wpf将静态变量绑定到控件属性

有时候需要将后台一个静态属性绑定到xaml前台&#xff0c;经过实践&#xff0c;有如下两种绑定的方式 例如后台声明一个类&#xff0c;类中包含静态变量&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T…

2023年金属非金属矿山(地下矿山)安全管理人员证模拟考试题库及金属非金属矿山(地下矿山)安全管理人员理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年金属非金属矿山&#xff08;地下矿山&#xff09;安全管理人员证模拟考试题库及金属非金属矿山&#xff08;地下矿山&#xff09;安全管理人员理论考试试题是由安全生产模拟考试一点通提供&#xff0c;金属非金…

【linux--进程通信之共享内存】

目录 一、共享内存的原理二、共享内存的数据结构三、共享内存使用的函数2.1ftok函数2.2shmget函数2.3shmctr函数2.4shmat函数2.5shmdt函数 四、实现进程通信 一、共享内存的原理 共享内存实际是操作系统在实际物理内存中开辟的一段内存。 共享内存实现进程间通信&#xff0c;是…

大数据之如何利用爬虫爬取数据做分析

目录 前言 爬虫概述 爬虫实现 1. 获取代理IP 2. 爬取数据 3. 多线程爬取 总结 前言 随着互联网和智能设备的普及&#xff0c;数据量逐年增长&#xff0c;数据分析和挖掘成为了热门领域&#xff0c;其中大数据分析技术和爬虫技术是重要的手段之一。本文主要介绍如何使用…

Python框架批量数据抓取的高级教程

一、背景介绍 批量数据抓取是一种常见的数据获取方式&#xff0c;能够帮助我们快速、高效地获取网络上的大量信息。本文将介绍如何使用Python框架进行大规模抽象数据&#xff0c;以及如何处理这个过程中可能遇到的问题。 二、项目需求 我们将爬取大量知乎文章&#xff0c;讨…

扁平化菜单功能制作

网页效果&#xff1a; HTML部分&#xff1a; <body><ul class"nav"><li><a href"javascript:void(0);">菜单项目一</a><ul><li>子菜单项01</li><li>子菜单项02</li><li>子菜单项03<…

matlab面向对象编程入门笔记

文章目录 1. 类和结构2. 定义类3. 属性3.1 private/protected/public属性3.2 constant属性3.3 hidden属性 4. 方法4.1 private/protected/public方法4.2 static方法4.3 外部方法 5. 动态调用6. 继承-超类6.1 handle超类6.2 dynamicprops 和 hgsetget子类 7. 封闭(sealed)类、方…

波奇学Linux:Linux进程状态,进程优先级

编写一个程序模拟进程 查看进程状态 修改代码后发现进程状态为由S变成R R为运行态&#xff0c;S为阻塞态 第一次为S是因为调用了外设&#xff08;printf调用屏幕外设&#xff09;&#xff0c;实际上应该为R&#xff0c;S状态轮换&#xff0c;但是R太快了&#xff0c;所以每次…

性能测试之Locust(完整版)

官方文档&#xff1a;Locust说明文档 一、Locust简介 1、定义 Locust是一款易于使用的分布式负载测试工具&#xff0c;完全基于事件&#xff0c;即一个locust节点也可以在一个进程中支持数千并发用户&#xff0c;不使用回调&#xff0c;通过gevent使用轻量级过程&#xff08…

订单管理系统开发经验的总结:优化流程、提升效率的关键实践

前言 一.订单管理系统的架构设计 二.订单系统的详细设计 1.拆分 2.换货 3.发货 4.拦截 5.取消 6.物流回传 三.订单系统的订单状态流转 初始状态 中间状态 异常状态 终态 四.订单系统的关键代码逻辑 五.结语 前言 两年来&#xff0c;整个订单管理系统经过大大小…

序列生成模型(一):序列概率模型

文章目录 前言1. 序列数据2. 序列数据的潜在规律3. 序列概率模型的两个基本问题 一、序列概率模型1. 理论基础序列的概率分解自回归生成模型 2. 序列生成 前言 深度学习在处理序列数据方面取得了巨大的成功&#xff0c;尤其是在自然语言处理领域。序列数据可以是文本、声音、视…