博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++对C语言的非面向对象特性扩充(3)
阅读量:5097 次
发布时间:2019-06-13

本文共 4042 字,大约阅读时间需要 13 分钟。

  今天要讲的是C++作用域运算符"::",强制类型转换的扩充,C++中相对于C中malloc和free函数的运算符new和delete,以及C++对C的一个重要扩充:引用(reference);这也是C++对C语言的非面向对象特性扩充系列的最后一节。

  1.如果有两个同名变量,一个是全局的,一个是局部的,那么局部的变量在其作用域拥有较高的优先权,全局变量则被屏蔽。那如果我希望在局部变量的作用域里使用全局变量怎么办,这时就要用到::作用域运算符了。比如:

1
#include
<
iostream
>
2
3
 
using
namespace
std;
4
5
 
int
x;
6
7
 
int
main()
8
9
{
10
11
  
int
x;
12
13
  x
=
50
;
14
15
  ::x
=
100
;
16
17
  cout
<<
"
局部变量x=
"
<<
x
<<
endl;
18
19
  cout
<<
"
全局变量x=
"
<<
::x
<<
endl;
20
21
  
return
0
;
22
23
}

结果:

  

  2.在C语言中有强制类型的转换比如:int x=1;double y=(double)x;而C++不但支持这种格式,还提供了一种类似于函数格式的转换:int x=1;double y=double(x);

  3.C中的malloc和free函数被用于动态分配内存和释放动态分配的内存,而在C++里,不但保留了这两个函数,另外使用运算符new和delete来更好地进行内存的分配和释放。内存分配的基本形式:指针变量名=new 类型,如:int *x;x=new int;或char *chr;chr=new char;释放内存(delete 指针变量名):delete x;delete chr;虽然new和delete的功能和malloc和free相似,但是前者有几个优点:(1)new可以根据数据类型自动计算所要分配的内存大小,而malloc必须使用sizeof函数来计算所需要的字节;(2)new能够自动返回正确类型的指针,而malloc的返回值一律为void*,必须在程序中进行强制类型转换;

  new可以为数组动态分配内存空间如:int *array=new int[10]或int *xyz=new int[8][9][10];释放时用delete []array和delete []xyz;另外new可以在给简单变量分配内存的同时初始化,比如int *x=new int(100);但不

 

能对数据进行初始化;有时候没有足够的内存满足分配要求,则有些编译系统将会返回空指针NULL,比如:

1
#include
<
iostream
>
2
3
 
using
namespace
std;
4
 
int
main()
5
{
6
int
*
x;
7
x
=
new
int
;
8
if
(
!
x)
9
{
10
cout
<<
"
分配内存失败!
"
<<
endl;
11
return
1
;
12
}
13
*
x
=
10
;
14
cout
<<*
x;
15
delete x;
16
return
0
;
17
}

  4.接下来详细地说一下C++的引用(reference),先解释一下,什么是引用?打个比方,一个人可能有三四个名字,但这三四个名字所做的事,其实就是那一个人所做的。引用就是给变量起了个别名罢了。它的格式:类型 &引用名=以定义的变量名;比如:

1
#include
<
iostream
>
2
3
using
namespace
std;
4
int
main()
5
{
6
int
x
=
100
;
7
int
&
y
=
x;
8
x
=
50
;
9
cout
<<
"
x=
"
<<
x
<<
endl;
10
cout
<<
"
y=
"
<<
y
<<
endl;
11
12
y
=
0
;
13
cout
<<
"
x=
"
<<
x
<<
endl;
14
cout
<<
"
y=
"
<<
y
<<
endl;
15
16
return
0
;
17
}

结果:

实际上,引用与其所代表的变量共享同一个内存单元,系统部位引用另外分配存储空间,编译系统使引用和其代表的变量具有相同地址。

1
#include
<
iostream
>
2
3
using
namespace
std;
4
int
main()
5
{
6
int
x
=
100
;
7
int
&
y
=
x;
8
x
=
50
;
9
cout
<<
"
变量x的地址:
"
<<&
x
<<
endl;
10
cout
<<
"
引用y的地址:
"
<<&
y
<<
endl;
11
return
0
;
12
}

结果:

发现其实引用就那么回事,但是也有几个注意点:(1)在声明引用时,必须立即对它进行初始化,不能声明完后在赋值:如int x=10;int &y;y=x;(2)引用的类型必须和给其赋值的变量的类型相同,不可以这样:int x;double &y=x;(3)为引用提供的值,可以是变量也可以是引用:int x=5;int &y=x;int &z=y;(4)引用在初始化后不能再被重新声明为另一个变量的引用:int x,y;int &z=x;z=&y;

  其实引用主要的用途就在于作为函数的参数,回顾一下,以前在C中传递函数参数有两种情况,分别是"传值调用"和"传址调用",前者传递是单向的,后者则为双向,而引用作为函数参数传递,则是"传址调用",它和C中指针作为参数传递的效果是一致的,只不过它不用像指针一样,需要交间接引用运算符"*";举个例子,比较一下这两种方法:

 
1
#include
<
iostream
>
2
3
using
namespace
std;
4
void
swap(
int
*
x,
int
*
y)
5
{
6
int
temp;
7
temp
=*
x;
8
*
x
=*
y;
9
*
y
=
temp;
10
}
11
12
void
swap(
int
&
x,
int
&
y)
13
{
14
int
temp;
15
temp
=
x;
16
x
=
y;
17
y
=
temp;
18
}
19
int
main()
20
{
21
int
i
=
10
,j
=
5
;
22
cout
<<
"
i=
"
<<
i
<<
"
j=
"
<<
j
<<
endl;
23
swap(
&
i,
&
j);
24
cout
<<
"
i=
"
<<
i
<<
"
j=
"
<<
j
<<
endl;
25
swap(i,j);
26
cout
<<
"
i=
"
<<
i
<<
"
j=
"
<<
j
<<
endl;
27
return
0
;
28
}

结果:

  对于引用,还有点小小的细节要说一下:(1)不能建立引用数组,比如:int a[4]="abcd";int &araay[4]=a;(2)不能建立引用的引用,不能建立指向引用的指针,比如:int x=50;int &&y=x;int &z=x;int *p=z;(3)可以把引用的地址赋给指针;(4)可以用const对引用加以限定,不允许改变引用的值,比如:int x=10;const int &t=x;t=5,但是x=5却可以,此时x和t都等于5;(5)引用运算符和地址操作符虽然都是&,但是引用的话,只是在声明时才用,而其它场合使用&都是地址操作符!比如:int x=5;int &y=x;y=10;int *z=&y//&为地址操作符;cout<<&z//&为地址操作符; 

  最后,我们还是用一个例子来总结一下今天所讲的内容(开发工具:vs2010):

 

1
#include
"
stdafx.h
"
2
#include
<
iostream
>
3
4
using
namespace
std;
5
6
int
x
=
10
;
//
全局变量
7
void
swap(
int
*
x,
int
*
y)
//
指针类型的参数
8
{
9
int
temp;
10
temp
=*
x;
11
*
x
=*
y;
12
*
y
=
temp;
13
}
14
15
void
swap(
int
&
x,
int
&
y)
//
带有引用类型的参数
16
{
17
int
temp;
18
temp
=
x;
19
x
=
y;
20
y
=
temp;
21
}
22
int
main()
23
{
24
double
*
y
=
new
double
(
5.55
);
//
new动态分配内存空间,字节大小和double类型所占字节一样,并初始化值
25
int
x
=
double
(
*
y);
//
强制类型转换
26
27
cout
<<
"
局部变量x=
"
<<
x
<<
"
全局变量x=
"
<<
::x
<<
endl;
28
swap(
&
x,
&
::x);
29
cout
<<
"
局部变量x=
"
<<
x
<<
"
全局变量x=
"
<<
::x
<<
endl;
30
swap(x,::x);
31
cout
<<
"
局部变量x=
"
<<
x
<<
"
全局变量x=
"
<<
::x
<<
endl;
32
33
delete y;
//
释放内存空间
34
return
0
;
35
}

 结果:

 

转载于:https://www.cnblogs.com/CaiNiaoZJ/archive/2011/07/09/2101942.html

你可能感兴趣的文章
一些方便系统诊断的bash函数
查看>>
【转载】基于vw等viewport视区相对单位的响应式排版和布局
查看>>
<转>关于MFC的多线程类 CSemaphore,CMutex,CCriticalSection,CEvent
查看>>
jquery中ajax返回值无法传递到上层函数
查看>>
css3之transform-origin
查看>>
[转]JavaScript快速检测浏览器对CSS3特性的支持
查看>>
Master选举原理
查看>>
[ JAVA编程 ] double类型计算精度丢失问题及解决方法
查看>>
小别离
查看>>
微信小程序-发起 HTTPS 请求
查看>>
WPF动画设置1(转)
查看>>
backgound-attachment属性学习
查看>>
个人作业——关于K米的产品案例分析
查看>>
基于node/mongo的App Docker化测试环境搭建
查看>>
java web 中base64传输的坑
查看>>
java 中的线程(一)
查看>>
秒杀9种排序算法(JavaScript版)
查看>>
素数判断BFS之“Prime Path”
查看>>
Activiti入门 -- 环境搭建和核心API简介
查看>>
struts.convention.classes.reload配置为true,tomcat启动报错
查看>>