C++和C#有关值类型和引用类型,以及对引用类型使用ref的效果

最近在把一个大型的C++程序移植部分内容到C#上,其中有大量的C#与C++双向交互。再封装接口的时候出现了不少对基础概念的考察,也巩固了对基础概念和C++与C#不同点的理解。在此记录下来。


今天先记录下C++和C#有关值类型和引用类型的区别。


对于C++来说,如果在函数中不标明&引用,就是按值传递。貌似除了数组是默认指针外,其他都是按值传递。自己编写了有关类和struct的程序进行了验证。


#include "stdafx.h"
#include <iostream>
using namespace std;


struct BPTest
{
public:
int val;
struct BPTest(int dfvalue)
{
val=dfvalue;
}

};
void SetVal2(BPTest* t,int tval)
{ 
t->val=tval;
return;
}
void SetVal1(BPTest t,int tval)
{
t.val=tval;
return;
}
void SetVal3(BPTest&t,int tval)
{
t.val=tval;
return;
}


int _tmain(int argc, _TCHAR* argv[])
{
BPTest t1(1);
BPTest* t2=new BPTest(2);
BPTest t3(3);
SetVal1(t1,10);
SetVal2(t2,10);
SetVal3(t3,10);
cout<<"t1: "<<t1.val<<"\n";
cout<<"t2: "<<t2->val<<"\n";
cout<<"t3: "<<t3.val<<"\n";
getchar();

return 0;
}



结果输出

t1: 1

t2:10

t3:10


把Struct换成Class的话,结果实测一样。

小结:可以看到,SetVal1实际是按值传递,做了类或struct的副本,所以更改不了原有类的值。SetVal2和3传递的相当于都是BPTest的对象地址,所以进行了修改。

进一步可以看到:c++里不像C#进行了值类型和引用类型的区分。


再谈一下C#的ref,值类型很好理解,如果对引用类型使用ref会产生什么效果呢?

看下面代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace BPCSharp
{
    class Program
    {
        public int val;
        public static void ChangeProperty(Program p1)
        {
            p1.val=111;
            return;
        }
        public static void ChangeSelf(Program p)
        {
            p=new Program(222);
            Console.WriteLine("changeself {0}", p.val);
            return;
        }
        public static void ChangeSelf2(ref Program p)
        {
            p=new Program(333);
            return;
        }
        public Program(int inVal)
        {
            val=inVal;
        }
        static void Main(string[] args)
        {
            Program p1=new Program(10);
            Program p2 = p1;
            Program p3 = new Program(30);
            Program p4 = p3;
            Program.ChangeProperty(p1);
            Console.WriteLine("p1 {0},p2 {1}", p1.val, p2.val);
            Program.ChangeSelf(p1);
            Console.WriteLine("p1 {0},p2 {1}", p1.val,p2.val);
            Program.ChangeSelf2(ref p3);
            Console.WriteLine("p3 {0},p4 {1}", p3.val, p4.val);
            Console.ReadLine();
        }
    }
}


结果输出

 p1:111 p2::111
changeself:222 
p1:111 p2::111
p3:333 p4:30


小结:ChangeProperty是按引用传递更改自身参数,所以p1,p1都有修改;

Changeself传入p1的引用,实际产生这个引用的副本,其存储的地址与p1和p2一样,指向p1数据存储的地址,函数内部将此引用变换成了一个新的地址,指向new Program(222),所以原来p1 p2没有变,只有函数内部的引用副本变化了。

ChangeSelf2传入p3引用的引用,既p3引用的存放地址,因此修改此值会让p3引用中存储的地址变化,指向new Program(333)的数据地址,因此p3变化,p4没有变化。


因此,C#中对引用使用ref是有不同的,需谨记!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值