C++之一些事一些情--函数传参

       C++中函数的参数传递方式,主要有两种,分别是值传递和引用传递,其中值传递包括传递普通变量和传递指针。下面会分别介绍三种变量传递方式的特点。

1、传递普通变量
       这种传递方式在函数内部会构造实参的一个副本,函数内部的操作并不会影响实参的值,对于内置类型不会有任何问题,而对于自定义的类类型就可能会带来一些问题。
1) 由于会构造实参的一个副本,因为消耗更多的时间和空间资源,效率低;
2) 可能会引起对象切割问题,即当形参为父类,而实参为子类时,属于子类的特殊化信息将会丢失。

       下面是一个例子:

class Base
{
public:
    virtual void Print(){ cout<<"Base"<<endl;}
};

class Derived : public Base
{
public:
    virtual void Print(){ cout<<"Derived"<<endl;}
};

       定义一个全局函数Print():

void Print(Base obj)
{
    obj.Print();
}

       下面会调用这个全局的Print函数,并以值传递的方式传递子类对象到父类对象中:

Derived derObj;
Print(derObj);  //输出结果为:Base

       上面代码的输出结果可以看出,传递对象方式传递子类对象时,会调用父类的拷贝构造函数生成实参的一个副本,在这个副本中,子类对象的信息被切割。

2、传递指针

       传递地址,其实就是把实参的内存地址传递给对应的形参,由于实参和形参都为指针,而且指向同一内存地址,因为可以通过形参修改实参所以内存地址的内容。但是传递指针并不能修改指针本身,请看以下例子:

void Construct(int *ptr)
{
    ptr = new int(10);
}

int *ptr = NULL;
Construct(ptr);
if (NULL == ptr)
    cout<<"NULL"<<endl;	//输出结果为:NULL
else
    cout<<"Not NULL"<<end;

       在传递指针的时候,函数内部也会构造实参指针的一个副本,函数内部的操作并不影响实参指针本身,影响的仅仅是副本,因此传递指针也属于值传递的一种。上述的例子不但不能得到想要的结果,而且也会造成了内存泄露问题。

       说到传递指针问题,如果传递的是一个数组名,数组指针会退化为一般指针,请看一下例子:

void GetLength(int *ptr)
{
    cout<<sizeof(ptr)<<endl;
}

int arr[10] = {0};
GetLength(arr);	//在32位系统下输出结果为:4

3、引用传递

       引用传递,传递的是变量本身,函数的形参在堆栈里面会开辟一个内存空间,里面存放的就是实参的地址,函数内部对形参的操作都会以间接寻址的方式访问实参本身。
       对于类类型变量,引用传递并不会调用类类型的拷贝构造函数,减少了资源的开销,而且效率更高,传递普通变量的方式其实就是与const引用一样,不过后者效率更高。

引用《Effective C++》对于函数参数传递的总结:
       除了内置类型、STL的迭代器和函数对象(后两者通常认为拥有高效的拷贝效率)可以被设计为值传递之外,其他任何类型都应该使用const引用传参(pass-by-reference-to-const)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值