c++ 参数传递机制

C++的参数传递机制 

C++一共有三种传递方式:值传递(pass by value)、指针传递(pass by pointer)、引用传递(pass by reference)。
关键点:在函数中,编译器总是要为函数的每个参数制作临时副本。引用传递除外。

一.值传递。

值传递很简单。唯一要注意的就是当值传递的输入参数是用户自定义类型时,最好用引用传递代替,并加上const关键字。因为引用传递省去了临时对象的构造和析构(见 关键点 )。
数据类型为内部类型时,不必。

例如:
将void Func(A a) 改为void Func(const A &a);
而void Func(int a)就没必要改成void Func(const int &a)。

二.指针传递。
今天之所以会花时间参阅C++的参数传递机制,就是因为对指针传递这一部分的应用出了问题。

例如:
在下面的getMemory函数中获得动态内存分配的指针p,并未能将获得的内存返回。

void getMemory(char *p, int num)
{
    p = new char[num];
}
 
void Test(void)
{
    char *str = NULL;
    getMemory(str, 100);    // str 仍然为 NULL
    strcpy(str, “hello”);        // 运行出错
    delete [] p;
}

出错的原因就是在于上面提到的 关键点
编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。
而在上例中,  副本_p申请了新的内存,只是把 _p所指的内存地址改变了,但是p丝毫未变 。所以函数getMemory并不能输出任何东西。并且,每执行一次getMemory就会泄露一块内存,因为没有用free释放内存。

解决方法有三种:

    甲)利用全局变量。
定义一个全局变量str,这样就不用把它作为参数来传递,也就不会有副本 _str。
char *str = NULL;
void getMemory(int num)
{
    str = new char[num];
}

    乙)用“指向指针的指针”。
void getMemory(char **p, int num)
{
    *p = new char[num];
}
void Test(void)
{
    char *str = NULL;
    getMemory(&str, 100);  // 注意参数是 &str,而不是str
    strcpy(str, “hello”);
    cout<< str << endl;
    delete [] str;
}

    丙)返回指针变量
char *getMemory(int num)
{
    char *p = new char[num];
    return p;

void Test(void)
{
    char *str = NULL;
    str = getMemory(100);
    strcpy(str, “hello”);
    cout<< str << endl;
    delete [] str;
}

三.引用传递。
C++区别于C的一个新增优势。虽然用&作为标识符,但是 跟指针一点关系都没有
int &a=b表示,a和b是同一个变量。简单地说,相当于一个别名,如: Stephen Chow 周星驰
当作为参数传递时,它省去了临时对象的构造和析构。

用法如下:
Func(int &a)
{
    a++;
}
void Test(void)
{
    int i;
    Func(i);
}

猜你喜欢

转载自blog.csdn.net/lwwl12/article/details/79286645