首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C++中使用

在C++中使用
EN

Stack Overflow用户
提问于 2011-11-16 23:32:49
回答 6查看 329关注 0票数 9

我想知道使用an &来访问某个内存位置会如何改变函数调用的性质。例如,如果我编写了一个函数来设置圆的半径

代码语言:javascript
复制
//True, if success, False if radius is off-screen
bool SetRadiusCircle(Circle &b, int r)

这是我的教授给我的作业中的一个例子。我只想知道他在示例函数调用中包含的"&“与简单地使用Circle b有什么不同。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-11-16 23:34:48

是。如果使用&,则将圆作为引用传递。如果你不使用它,你就是在传递circle对象的一个副本,这个副本是由编译器为你创建的。这会触发类复制构造函数(要么是您定义的构造函数,要么是默认的按位复制构造函数)。

使用引用时,您不是在复制对象。取而代之的是获取调用者中的对象。它相当于原始对象的别名,您执行的任何更改都将应用于传递的对象。在副本的情况下,对对象的任何更改都会在调用结束时丢失,因为副本会被销毁。

当您使用引用时,该参数的内部使用要求您使用.来访问该对象的成员(例如b.getRadius())。如果您将函数定义为接受指针(func (Circle *bPtr)),则必须使用-> (例如bPtr->getRadius())。使用指针与使用引用不同,但最终的实际效果是相同的:您可以操作原始对象,而不是副本。

请注意,这在函数定义中是有效的。在另一个上下文中使用&可以给出某物所在位置的指针。尽管它们使用相同的符号,但它们并不相同。

票数 22
EN

Stack Overflow用户

发布于 2011-11-16 23:35:10

这里的&指的是引用

它只是一个被传递变量的别名。

在函数内部对b执行的任何修改都将导致对传递给函数的对象进行修改。

如果没有&,对象的副本将被传递给函数,并且在函数中对其执行的任何修改都不会修改原始对象。

详细说明:

考虑下面这个简单的示例,它演示了将参数传递给函数的3种方法:

传递值:

代码语言:javascript
复制
void passByValue(MyClass obj)

当通过值传递函数参数时,函数将接收所传递变量的副本,在函数体中对此副本所做的任何修改都不会影响所传递的原始变量。

传递引用:

代码语言:javascript
复制
void passAnRef(MyClass &ref)

该函数接收变量的别名,该变量是在该别名modify上执行的passed.Any修改,也是原始变量。如果传递的参数是一个自定义类对象,那么您可以访问类成员,就像使用.操作符通过对象访问一样。

传递一个指针:

代码语言:javascript
复制
void passAnPtr(MyClass *ptr)

该函数接收指向被传递的原始变量的指针。即:它接收一个变量,该变量指向内存中原始变量的地址。通过这个指针执行的任何修改都会修改原始对象,因为它只是指向那个内存。

如果传递的参数是一个自定义类对象,那么您可以访问类成员,就像使用->操作符通过指向对象的指针进行访问一样。

代码语言:javascript
复制
#include<iostream>
using namespace std;

class MyClass
{
    public:
         int i;
         MyClass():i(0){}
};

void passByValue(MyClass obj)
{
    obj.i = obj.i + 10;

}
void passAnRef(MyClass &ref)
{
    ref.i = ref.i + 10;
}
void passAnPtr(MyClass *ptr)
{
    ptr->i = ptr->i + 10;
}

int main()
{
    MyClass obj;

    cout<<"Before passByValue obj is:"<<obj.i;
    passByValue(obj);
    cout<<"\nAfter passByValue obj is:"<<obj.i;

    cout<<"\nBefore passAnRef obj is:"<<obj.i;
    passAnRef(obj);
    cout<<"\nAfter passAnRef obj is:"<<obj.i;

    cout<<"\nBefore passAnPtr obj is:"<<obj.i;
    passAnPtr(&obj);
    cout<<"\nAfter passAnPtr obj is:"<<obj.i;

    return 0;
}

输出:

passByValue obj之前的

为:0

在passAnRef obj is:0之前,passByValue obj is:0之后

在passAnPtr obj is:10之前,passAnRef obj is:10之后

在passAnPtr obj is:20 之后

票数 5
EN

Stack Overflow用户

发布于 2011-11-16 23:36:26

区别在于Circle &c是通过引用传递的,而Circle c是通过值传递的。

当通过值传递时,将创建对象的副本,因此,例如,如果您在函数内更改对象,则更改不会反映在函数外部。当通过引用传递时,您将获得对实际对象的引用,并且函数内部的任何更改都将对调用者可见。

不用说,“对象的副本已创建”意味着调用copy c‘’tor。

例如。

代码语言:javascript
复制
#include <iostream>

class My {
public: int x;
};

void byVal(int a, My m) {
    std::cout << "\tentry byVal(): " << i << "--" << m.x << std::endl;
    ++a; ++m.x;
    std::cout << "\texit byVal(): " << i << "--" << m.x << std::endl;
}

void byRef(int &a, My &m) {
    std::cout << "\tentry byRef(): " << i << "--" << m.x << std::endl;
    ++a; ++m.x;
    std::cout << "\texit byRef(): " << i << "--" << m.x << std::endl;
}

int main() {
    My m; m.x = 10; int i = 10;
    std::cout << "before: " << i << "--" << m.x << std::endl;
    byVal(a,m);
    std::cout << "after byVal(): " << i << "--" << m.x << std::endl;
    byRef(a,m);
    std::cout << "after byRef(): " << i << "--" << m.x << std::endl;
}

将打印

代码语言:javascript
复制
    before: 10 -- 10
        entry byVal(): 10 -- 10
        exit byVal(): 11 -- 11
    after byVal():  10 -- 10
        entry byRef(): 10 -- 10
        exit byRef(): 11 -- 11
    after byRef():  11 -- 11
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8154210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档