免费视频|新人指南|投诉删帖|广告合作|地信网APP下载

查看: 1848|回复: 1
收起左侧

[技术交流] c++/java/c# 几种编程语言的指针、引用比较

[复制链接]

6

主题

1964

铜板

10

好友

助理工程师

Rank: 5Rank: 5

积分
253
发表于 2012-6-9 17:55 | 显示全部楼层 |阅读模式
java 中的引用/指针,与 c++/C# 中的引用/指针不是一个概念.
Java 引用,相当于 c++ 指针(fun3)。Java 引用可以赋值 null, 而 c++ 引用 (见 fun2) 不能赋值 null,c++ 指针可以赋值 null(fun3).
Java 中,无 c++ 引用(fun2)对应的语法。
结果引起不必要的质疑,特此,写博客,对c++/java/c# 几种编程语言的指针、引用,进行比较,期望引起更多的人,对此有所关注。
从语法上看,三种开发语言中,C++ 的指针、引用,最为复杂,因此,下面的举例,都从 C++ 代码开始,然后与 java/c# 的语法进行比较。
1)  C++ 简单类型变量,有直接变量定义、指针定义、引用定义。
    int aa = 10;//c++
    int &bb = aa;//c++
    int *cc = &aa;//c++
上述三行代码,最后三个变量指向同一个数据。相比较而言,java/c# 都只有变量定义,无引用定义、指针定义。

2) C++ 函数调用参数,简单类型变量,有直接变量定义、指针定义、引用定义,后两个,在函数内部改变数据,退出函数,能看到改变后的数据。

void simple_by_val(int a, const int b)
{
    a=15;
    //b=13;            //error C2166: l-value specifies const object
    //a=NULL;        //good
    //b=NULL;        //error C2166: l-value specifies const object
}
void simple_by_ref(int &a, const int &b)
{
    a=25;
    //b=23;            //error C2166: l-value specifies const object
    //a=NULL;            //good
    //b=NULL;        //error C2166: l-value specifies const object
}
void simple_by_pointer(int *a, const int *b)
{
    *a = 35;
    //*b = 33;        //error C2166: l-value specifies const object
    a = NULL;        //ok
    b = NULL;        //ok
}
java 没有这么多名堂,只有直接变量定义。C# 略为复杂一点,有引用,有 out 参数。
        static void M(int a, ref int b, out int c)
        {
            c = 13;
        }
相比较而言,C# 的函数参数( ref int b), 类似于C++的函数参数( int &a),都是调用函数前要赋初值,在函数内部改变数据,退出函数,能看到改变后的数据。
而 C# 的 (out int c),在 C++/Java 中,无对应的语法。这个可以调用函数前,不赋初值。在 C# 之前,也很少见到这种语法,只在一些数据库的存储过程、函数定义中,见过类似语法。估计是从数据库编程语法中抄袭过来的语法。
特别注明:C# 的引用,只是用在函数参数变量定义上,不能用在函数内部的局部变量中。C++ 中的引用,可以用在函数内部的局部变量中。

3)  C++ 的类对象语法,较为复杂,可以定义在stack 上(不用 new),可以定义在 heap(用 new)。
    CMyClass obj;                        //stack
    CMyClass *p2 = new CMyClass();        //heap
java/C# 中,没有这么复杂,可以认为是上述两种“综合+简化”了。

4) 在 java/C# 中,如下用法是错误的,会报空指针异常;但是在 C++ 里是合法的。
    CMyClass obj;
    obj.run();
在 C++ 中,
CMyClass obj;
以上一行代码已经调用了构造函数,完成了变量初始化。而在 java/C# 中,这一行代码相当于:

CMyClass obj = null;

5) C++ 中,stack 变量出了作用范围,内存自动回收;heap 变量,需要手工 delete。

java/C# 中,变量是空闲时自动回收的(理论上的),不是变量出了作用范围,就内存回收。


6) 以下代码在 C++ 中,是错误的,而在 java/C# 中,是正确的。


CMyClass obj = null;


7) 以下代码在 C++ 中是正确的,在 java/C# 是错误的。在 java/C# 语法中,没有定义变量加 * 的。
CMyClass *p1 = null;
CMyClass *p2 = new CMyClass();

8) 以下代码,在java/C# 语法中,是正确的,在 C++ 是错误的。
CMyClass p1 = null;
CMyClass p2 = new CMyClass();

9) 以下代码,在 C++ 代码中,会调用“拷贝构造函数”、"等于号重载函数"。这两个函数,在 C++ 中,默认会由编译器自动生成。
    //C++    CMyClass obj;              //调用构造函数
    CMyClass obj2 = obj;   //调用拷贝构造函数
    obj2 = obj;                  //调用 = 重载函数
以上代码,大致相当于 java/C# 中的 克隆"clone"。但更隐蔽、更复杂。
//C#
            CMyClass obj = new CMyClass();
            CMyClass obj2 = (CMyClass)obj.Clone();
而在 C# 中,Clone 函数并不会自动生成。在 Java 中,可以调用 super.clone();
在 C++ 中,默认会由编译器自动生成“拷贝构造函数”、"等于号重载函数",这一点,很多时候会造成问题,要特别注意。
在 C++ 中,函数返回值不要用 CMyClass ,这会造成不必要地调用“拷贝构造函数”、"等于号重载函数";也不要返回引用 CMyClass&, 对函数内局部变量的引用,退出函数后无法继续使用。而要返回指针 CMyClass *。这一点很多初学者不明白。
但是 C++ 的 std:string 除外。std:string 的“拷贝构造函数”、"等于号重载函数"经过优化,拷贝后的变量,与拷贝之前的变量,内部使用相同的 char[] 数组,只有当一个 string 变量改变时,才会把 char[] 数组复制成两份。std:string 的“拷贝构造函数” 没有性能上损失,又比 string 指针减少了内存泄露,因此,对 std:string ,使用时尽量用 对象变量、对象引用、对象拷贝构造,避免使用 std:string 指针。

10) Sun 自称 java 中消灭了 C++ 中万恶的指针,只有自己的对象变量都是引用。做个比较:
C++ 引用不能赋值 null, 不能赋值 new XXX();C++ 指针可以赋值 null, 可以赋值 new XXX()。
C++ 引用对象通常在 stack 中,而C++ 指针 new 出来的对象则在 heap 中。

java/C# 中的对象变量,可以赋值 null, 可以赋值 new XXX()。java/C# 中的对象变量在 heap 中。

因此,java/C# 中的对象变量,更像是 C++ 中的指针,而不是 C++ 中的引用。

11) C++ 中,指针变量是一个 long 型整数,可以乱指的:
CMyClass *obj = (CMyClass *) 99;        //compile/run good, should not use   
如果我知道一个内存地址,就可以定义一个C++指针变量,指向这个内存地址。C++ 的“引用”没有这个功能。C#/Java 的对象变量更没有这个功能。
“指针乱指” 是 C++ 指针功能强大、灵活的体现,也是最容易出问题的地方。估计是因为这个原因,所以C#/Java 都去掉了这个功能。所谓“万恶的C++指针”,多半,也是指的是“指针乱指”。

另,有人抱怨,面试做题,看不是是 C++ 还是 Java、C# , 期望通过看本文,可以帮助一二。
出处华夏土地网:http://bbs.hxland.com/forum.php?mod=viewthread&tid=7495722&extra=

0

主题

2230

铜板

15

好友

地信院士

Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15

积分
2033
发表于 2021-6-21 16:51 | 显示全部楼层

感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

在线客服
快速回复 返回顶部 返回列表