• C++对C语言的非面向对象特性扩充(3)


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

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

    复制代码
    1 #include<iostream>

    3  usingnamespace std;

    5  int x;

    7  int main()

    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   return0;
    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>

    3  usingnamespace std;
    4  int main()
    5 {
    6 int*x;
    7 x=newint;
    8 if(!x)
    9 {
    10 cout<<"分配内存失败!"<<endl;
    11 return1;
    12 }
    13 *x=10;
    14 cout<<*x;
    15 delete x;
    16 return0;
    17 }
    复制代码

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

    复制代码
    1 #include <iostream>

    3 usingnamespace 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 return0;
    17 }
    复制代码

    结果:

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

    复制代码
    1 #include <iostream>

    3 usingnamespace 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 return0;
    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>

    3 usingnamespace 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 return0;
    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>

    4 usingnamespace std;

    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=newdouble(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 return0;
    35 }
    复制代码

     结果:

     

     
  • 相关阅读:
    Leetcode#104. Maximum Depth of Binary Tree(二叉树的最大深度)
    Leetcode#70. Climbing Stairs(爬楼梯)
    Leetcode#88. Merge Sorted Array(合并两个有序数组)
    美团2019秋招后台开发编程题题解
    Leetcode#191. Number of 1 Bits(位1的个数)
    Leetcode#461. Hamming Distance(汉明距离)
    Leetcode#13. Roman to Integer(罗马数字转整数)
    Leetcode#521. Longest Uncommon Subsequence I(最长特殊序列 Ⅰ)
    Leetcode#557. Reverse Words in a String III(反转字符串中的单词 III)
    带你剖析WebGis的世界奥秘----瓦片式加载地图
  • 原文地址:https://www.cnblogs.com/wvqusrtg/p/4498327.html
Copyright © 2020-2023  润新知