-5

我需要对按值/指针/引用传递的一劳永逸的澄清。

如果我有一个变量,例如

int SomeInt = 10;

我想把它传递给一个像

void DoSomething(int Integer)
{
    Integer = 1;
}

在我当前将 SomeInt 传递给 DoSomething() 的情况下,我希望 SomeInt 的值根据我们在 DoSomething() 中对其所做的任何事情进行更新,并且在内存和性能方面最有效,所以我不会复制变量? . 话虽如此,以下哪个原型可以完成这项任务?

void DoSomething(int* Integer);
void DoSomething(int& Integer);

我实际上如何将变量传递给函数?前两个原型有什么区别?

最后,如果在类中使用函数

class SomeClass
{
    int MyInteger;

public:
    void ChangeValue(int& NewValue)
    {
        MyInteger = NewValue;
    }
};

如果我将一个整数传递给 ChangeValue,当我传入的整数被删除时,这是否意味着当我尝试在类中使用 MyInteger 时,它将不再可用?

谢谢大家的时间,我知道这是一个基本的问题,但我不断遇到的解释让我更加困惑。

4

4 回答 4

4

你的两个例子

void DoSomething(int* Integer);
void DoSomething(int& Integer);

将完成任务。在第一种情况下 - 使用指针 - 您需要使用 调用函数DoSomething(&SomeInt);,在第二种情况下 - 使用引用 - 更简单DoSomething(SomeInt);

推荐的方法是在引用足够时使用引用,并且仅在必要时使用指针。

于 2014-07-17T09:12:05.990 回答
4

在功能上,所有这三个工作:

  • 传递一个int并将返回类型更改为int以便您可以返回新值,用法:x = f(x);

    • 当您计划在不需要读取初始值的情况下设置值时,最好使用这样的函数,int DoSomething();这样调用者就可以说int x = f();而不必x在前面的行上创建并且想知道/担心它是否需要在之前初始化任何东西通话。
  • 传递一个int&并将其设置在函数内部,用法:int x; x = ? /* if an input */; f(x);

  • 在函数内部传递一个int*并设置指向int,用法:int x; x = ?; f(&x);

在内存和性能上最有效,所以我不会复制变量

鉴于 C++ 标准并未规定编译器应如何实现引用,因此尝试推理它们的特性有点可疑 - 如果您关心将代码编译为汇编代码或机器代码并查看它在您的特定编译器上的效果(对于特定的编译器命令行选项等)。如果您需要经验法则,请假设引用具有与指针相同的性能特征,除非分析或生成代码检查另有建议。

对于一个int您可以期望上面的第一个版本不会比指针版本慢,并且可能更快,因为int参数可以在寄存器中传递和返回,而无需内存地址。

如果/何时/在哪里内联了按指针版本,则可能很慢的“需要内存地址以便我们可以传递指针”/“必须取消引用指针以访问/更新值”方面的传递-可以优化逐指针版本(如果您要求编译器尝试),使两个版本具有相同的性能......

尽管如此,如果您需要问这样的问题,我无法想象您正在编写代码,其中这些是重要的优化选择,因此更好的目标是为您提供最干净、最直观和最强大的客户端使用代码......现在 - 无论是x = f(x);(您可能会忘记前导的地方x =),还是f(x)您可能没有意识到x可以修改的f(&x)地方,或者(某些调用者可能认为他们可以通过的地方nullptr本身就是一个合理的问题,但与您的性能问题。FWIW,C++ FAQ Lite 建议在这种情况下引用指针而不是指针,但我个人拒绝它的推理和结论——这一切都归结为熟悉这两种约定,以及你需要多久通过一次const指针值或指针值nullptr是有效标记,可能会与您的场景中希望的你可以修改我的含义相混淆......这在很大程度上取决于你的编码风格、你使用的库、问题域等..

于 2014-07-17T09:21:23.127 回答
0

如前所述,您可以同时使用两者。的优势

void DoSomething(int* Integer)
{
  *Integer=0xDEADBEEF;
}
DoSomething(&myvariable);

模式是,从调用中可以明显看出 myvariable 可能会发生变化。

的优势

void DoSomething(int& Integer)
{
  Integer=0xDEADBEEF;
}
DoSomething(myvariable);

模式是 DoSomething 中的代码更干净,DoSomething 更难以不好的方式弄乱内存,并且您可能会从中获得更好的代码。缺点是,从读取调用 myvariable 可能会被更改的过程中并不能立即看出这一点。

于 2014-07-17T09:19:46.227 回答
0

你可以使用任何一个。第一个原型的函数调用将是

DoSomething(&SomeInt);  

对于第二个原型

DoSomething(SomeInt);  
于 2014-07-17T09:09:24.183 回答