PoEdu - C++阶段班【Po学校】- 第3天
引用 |


C中指针的功能强大,使用起来繁杂,因为指针要控制的东西太多:有指针的类型,指针的解引用,指针空间内的值,它本身是有空间的,有自己的地址等。指针也是强大的,比如:我们要在函数之内,修改方法之外的值的话,必需用到指针。但这里指针的使用,使得我们要修改的类型,变成了另外一种类型(如:int*)由原来的类型变成了指针类型。
| 引用 & 能实现指针一模一样的功能,但它不改变数据的状态(类型)。 |
.png)
用法:int val = 100; int &refval = val ;
指针我们可以直接指向一个NULL,但引用必需要指向一个变量。这是与指针不一样的地方。引用是变量的别名。
1 引用是没能独立空间的,所以它一定要与一个变量绑定,才能共用一段空间。
2 引用确定后,它无法被更改。一旦经理室了一个对象,就无法再次赋值为别的对象。

上图所有针对refval的操作,都作用在绑定的变量val上。
3 引用,它与引用 的变量共用同一段空间
示例:
#include <iostream>
using namespace std; void Swap(int &rhs, int &lhs)
{
int tmp = rhs;
rhs = lhs;
lhs = tmp;
} int main()
{
int val = ;
int &refval = val ; int num = ;
//refval = num; //这里示范,相当于这样:val = num Swap(val,num);
cout << val << " " << num ; return ;
}
运行: 50 100
数据交换成功。


引用它是安全的,可以理解为阉割版的指针:
#include <iostream> void Swap(int &rhs,int &lhs)
{
int tmp = rhs;
rhs = lhs;
lhs = tmp;
} int main()
{
int val = ;
int &refval = val; //引用是变量的别名,更多是在语法层面的。
//它是没有独立空间的;
//引用确定后,它的值是不能更改的。
// 共用同一空间
int *pVal = &val; val = ;
std::cout << val; //
std::cout << refval; //
std::cout << pVal; //val地址
std::cout << *pVal; //50 //Swap(val, num); return ;
}
断点 运行:

再看:

运行:

再再看:

运行如下:


引用的意义在于:代码的可读性更强,并且安全,但凡一引用,永远无法更改。
|
提问:这两种写法正确吗? 1 // int &refval = 100; 2 //int *pval = &100; 这样子是不行的: 看1的代码,一个引用int &refval等于一个立即数100,立即数100是没有内存地址的,也就是没有空间的,虽然说引用没有独立的空间,但它指向一个变量后,也就是要有空间的,共享空间而已。这里立即数不在内存里面产生,在内存中没有空间,所以1的写法是错误的。 看2的代码,左边是一个int * 的指针pval,等号后面,把100这个立即数的地址,赋值给左边的指针?~!立即数在寄存器里面产生,不在内存中存在。很显然,示例2的代码也是错误的。 |
.png)
复习C语言中 const 的用法
1 示例 代码:const int *pVal = &val; 请问:这段代码const修饰了什么?是什么不能修改?是地址pval,还是解引用的值不能修改?用编译器的贪心法则来套用:const先看左边,左边为空,那转向右边,第一个int ,再看第二个*,可以修饰,再看pVal,最后遇到赋值等号,那么const有效的修饰3个连接:int *pVal,得出结论:*pVal解引用的值被const修饰,值不能修改。
2 示例 代码:int const *pVal = &val; 这段代码又是什么不能修改? 当const在*号的左边时,和代码1一样。
3 示例 代码: int * const pVal = &val; 当const在*号的右边时:(看口诀:左数右指。)那么就是这根“指针”本身不能被改变。就是指针里面的内存地址(俗称一根指针)。

在C++中const 和&引用一块使用会产生什么化学反映呢?
示例 //const int &refval = val; 这里是什么无法修改呢? A 值 B 地址
答案是:以上都不正确,因为const的引用,要指向const修饰的类型
如:const int num = 500; const int & refnum = num; 这样出现才是正确的。如果你要引用一个常量的话,前面一定要加上const修饰。

.png)


.png)

运行,交换成功!
|
函数void Swap(int &rhs, int &lhs); 相当于传递了指针地址,也就是说传递了引用 的共享空间,在C中我们用指针,C++中我们用引用。可以这么认为:它将函数形参实参化了。引用相当于直接传递了本身(地址)。好处就是:函数内将参数作为变量使用,作用于外部。 函数之间的值传递是通过栈来完成的,如果我要传递的是一个比较大的结构体,那么这里就可以使用“&引用”,传递地址以节省空间。 实际上我们想传递引用时,常见的情况下,只需要传递地址,数据并不想被修改,那么,引用要加上const 来修饰,以避免被修改的风险。而且下面调用函数时,并不用写上const对应参数,因为它会自动做一个提升。 引用还可以作为函数的返回 |
.png)

|
引用作为返回值的写法 |
看代码 1
#include <iostream>
int array[] = { ,,,, };
int &Index(int index)
{
return array[index];
}
int main()
{
Index() = ;
return ;
}
代码 2
#include <iostream>
int array[] = { ,,,, };
int &Index(int index)
{
return array[index];
}
int *Index()
{
retrun &array[];
}
int main()
{
Index() = ;
*Index() = ;
return ;
}
以上是返回引用与返回指针的写法。
这里打印指针和引用,直观的认识指针和引用之间的区别:
#include <iostream>
int array[] = { ,,,, };
int &Index(int index)
{
return array[index];
}
int *Index()
{
return &array[];
}
int main()
{
Index() = ;
*Index() = ;
std::cout << array[] << " " << Index();
//100 //地址
int num = ;
int &ref = num, *p = #
std::cout << ref << p << *p;
//0 //地址//
return ;
}
|
引用能不能取代指针呢?答:不能,因为引用不能指向推空间。 C++很强大:请看这行代码 int *&refp = p; |
.png)

|
C++11中间的auto 自动推导所需类型 这里有行永远也不要写的代码:*p = num; auto &refp = p; 永远不要拿一个指针去做它的引用。 |
.png)
|
类与对象
|
.png)
|
类:比如人类,虚的,抽象的,出现在人们口中,出现在纸上,是一个概念性的,属性的集合。 |
.png)
|
对象:实体的,活生生的,能动能说能笑,吃喝拉撒……
|
.png)
.png)
.png)
|
C++中的类:公有 public : 私有 private : 默认私有。 私有属性只能类内部访问。 |
.png)
|
其实还有一种 protected : 受保护的。 |
.png)
|
构造函数与析构函数 |
.png)
代码:
#include <iostream> class MyString
{
char *str;
int len;
public:
MyString() //构造函数
{
std::cout << "MyString()被调用" << std::endl;
}
~MyString() //析构函数
{
std::cout << "~MyString()被调用" << std::endl;
}
int &Len()
{
return len;
}
}; int main()
{
MyString demo;
demo.Len() = ; return ;
}
断点运行:
构造函数与类名相同,没有返回值你不写,编译器默认生成 |
.png)
当对象产生时,构造函数被调用。 |
.png)
析构函数 当对象销毁时,析构函数被调用 |
.png)

|
当你创建了构造函数,编译器不会再自动生成构造函数。 析构函数里面,写入释放内存的代码,是常见的手法。 |
.png)

|
我们无法直接:类.方法 因为类是虚的,是图纸,是设计方案,是汽车图纸,只有实体小车,才有车门,有方向盘,所以老司机要开车,首先要有个对象:一辆车。在计算机的世界里面,类不占内存,对象才占用内存。占用内存的,才是实体对象。 对象是实体的,就如一块实体的手表,手表设计图纸就是类,工厂按设计图纸加工,材料是各属性变量等,默认构造成一个什么样子,就有了构造函数,不合格就的产品要收回,就有了析构函数。所以每个手表(对象)就有初始的大致的模样和功能(构造函数 ),还有回收方法(析构函数),有些是在表面可见的,可以控制的(public权限),而有些是封闭在手表内部,是不可见的(private权限); 现得知一个类:构造函数带有参数,如果想创建不带任何参数的对象,两种方法:1 构造函数重载,加一个没有任何参数的构造函数;2 在现有的参数里面写入默认实参。 |
.png)
|
类 内部变量书写规范 加下划线 |
.png)
作业:
.png)

附上代码,以及一个小发现:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring> class MyString
{
char *_str;
int _len;
public:
MyString()
{
_str = new char[];
_len = ;
}
MyString(char *str)
{
_len = strlen(str);
_str = new char[_len+ sizeof(char)];
strcpy(_str, str);
}
~MyString() //析构函数
{
delete[]_str;
}
char *GetString()
{
return _str;
}
}; int main()
{
MyString demo1; MyString demo2(); //前者是新建一个以demo1命名的对象,后者是声明一个返回MyString类型的函数demo2(). MyString demo("I Love Mark");
std::cout << demo.GetString();
return ;
}
检验一下上面高亮的demo2,看它到底是对象,还是方法。

验证说明:demo2是方法,不是对象。
.png)
PoEdu - C++阶段班【Po学校】- 第3天的更多相关文章
- PoEdu - C++阶段班【Po学校】- Lesson03-4_构造函数&赋值函数&拷贝构造函数&学习方式 - 第6天
PoEdu - C++阶段班[Po学校]- 第6天 课堂选择题目: 1 关于转换构造函数 ClassDemo demo = 1; 调用转换构造函数 2 关于拷贝赋值函数 demo =2; 首 ...
- PoEdu - C++阶段班【Po学校】- Lesson02_类与对象_第4天
复习:上节作业讲解 注意点: 设计SetString()的时候,要注意重置原来的空间. char * SetString(const char *str) { _len = strlen(str); ...
- PoEdu - C++阶段班【Po学校】- 第1课
1 C++开讲 C ++ 伟大的编程语言:能提高程序运行效率,节约更多的资源,"正确的使用C++,能够抑制全球变暖问题". 2 C++能力雷达图 通过 1效率 2灵活度 3 抽象 ...
- PoEdu - C++阶段班- Lesson07 To Lesson10_C to C++
07 重载导致的二义性 问题:为什么一定要重载呢?重载能方便我们注重函数的功能,当参数类型不确定时,我们能很便捷的利用重载的机制达到目的. 重载注意点:二义性 看代码: #include <c ...
- PoEdu - C++阶段班- Lesson02_C to C++
1 原生bool类型 c++里面的bool类型才是真正原生的true和faul,比如常见的大写的"BOOL",它就不是原生的. 原生的与非原生的bool,它们的区别: 详细说下原 ...
- PoEdu- C++阶段班【Po学校】-Lesson03_构造函数精讲 - 第5天
复习构造函数:1 与类同名 2 没有返回值 3 自动生成 4 手动后,不会自动生成 5 不在特定的情况下,不会私有 新建 类 两种方法示范 其一:在vs中选择类 ...
- PoEduo - C++阶段班【Po学校】-Lesson03-5_运算符重载- 第7天
PoEduo - Lesson03-5_运算符重载- 第7天 复习前面的知识点 空类会自动生成哪些默认函数 6个默认函数 1 构造 2 析构 3 赋值 4 拷贝构造 5 oper ...
- 九、Python+Selenium模拟用QQ登陆腾讯课堂,并提取报名课程(练习)
研究QQ登录规则的话,得分析大量Javascript的加密解密,比较耗时间.自己也是练习很少,短时间成功不了.所以走了个捷径. Selenium是一个WEB自动化测试工具,它运行时会直接实例化出一个浏 ...
- 九、Python+Selenium模拟登录
研究QQ登录规则的话,得分析大量Javascript的加密解密,比较耗时间.自己也是练习很少,短时间成功不了.所以走了个捷径. Selenium是一个WEB自动化测试工具,它运行时会直接实例化出一个浏 ...
随机推荐
- java8之接口增强
Java8是由oracle公司于2014年3月正式发布,它是继java5 以来最重要的发布版本.Java8包含了很多新的特性,可以简化开发,提升代码的可读性. Java8的一些重要新特性包括: l 接 ...
- 泛型(Generic)
本质:限制集合类型 我们在编写泛化类的时候,我们要时刻提醒自己,我们传入的参数T仅仅是一个Object类型,任何具体类型信息我们都是未知的. 小例子: package day02.generic; i ...
- Linux 之加密类型,CA,Openssl,Openssh
TCP/IP:安全 A------->B 机密性:明文传输(ftp,http,smtp,telnet),被窃听 完整性:消息被篡改 身份验证:你访问的主机就是你真实要访问的那台,而不是钓鱼网站 ...
- jquery 使用方法(二)
jquery語法: jquery語法是為html元素的选取编制的,可以对元素执行某些操作. 基础语法是:$(selector).action() 美元符号定义 jQuery 选择符(selector) ...
- This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms while caching 问题及解决
一.背景 情节1:做别的测试安装下载了软件,妈蛋结果下了百度各种捆绑软件,之后一一卸载,清洁. 情节2:做完上述动作重启电脑后,有线连接连不上,尴尬,然后下载驱动,升级之后ok了. 二.问 ...
- DotNet Core 1.0 集成 CentOS 开发与运行环境部署
一. DotNet Core 1.0 开发环境部署 操作系统安装 我们使用CentOS 7.2.1511版本. 安装libunwind库 执行:sudo yum install libunwi ...
- Redis从基础命令到实战之散列类型(Hash)
从上一篇的实例中可以看出,用字符串类型存储对象有一些不足,在存储/读取时需要进行序列化/反序列化,即时只想修改一项内容,如价格,也必须修改整个键值.不仅增大开发的复杂度,也增加了不必要的性能开销. 一 ...
- SQL Server(三):Select语句
1.最基本的Select语句: Select [Top n [With Ties]] <*|Column_Name [As <Alias>][, ...n]> From & ...
- Spark 2.6.1 源代码在 eclipse 的配置
本文地址:http://www.cnblogs.com/jying/p/3671767.html 这么个问题又耗费了偶一天时间,真是羞愧.. 上午从官网svn地址下载最新的 spark 包,总是下载失 ...
- VS2010项目的部署与安装
VS2010项目的部署与安装 转自:http://www.cnblogs.com/smile-wei/archive/2012/07/06/2579607.html winform程序,我想进行安装. ...