通过数值/指针/参考说明

问题描述:

我需要一次一个和所有的澄清值传递/指针/参考。通过数值/指针/参考说明

如果我有一个变量如

int SomeInt = 10; 

而且我想通过SomeInt时DoSomething的()我想SomeInt的价值,它像

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

传递给函数在我目前的情况下根据我们在DoSomething()里面对它做的任何事情来更新,以及在内存和性能方面最有效率,所以我不会复制变量?这是说以下哪个原型可以完成这项任务?

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

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

最后,如果使用函数的类

class SomeClass 
{ 
    int MyInteger; 

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

内如果我整数关口进入ChangeValue,在整数i中获取的删除通过将意味着,当我尝试使用MyInteger从类它将内不再可用?

谢谢大家的时间,我知道这是一个基本的问题,但我继续陷入困惑的解释进一步。

+0

是,这些功能可能会完成任务。 –

+3

-1我会对一生中的一次澄清感兴趣,人们如何打算学习像C++这样复杂的编程语言,而不必查看基本的学习材料。 – Solkar

+0

您可能有兴趣阅读常见问题解答问题http://stackoverflow.com/questions/2139224/how-to-pass-objects-to-functions-in-c – Cecilia

功能,所有这三个工作:

  • 传递一个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);

最高效的内存和性能,所以我不是抄袭周围

变量3210

考虑到C++标准并没有规定如何通过编译器实现引用,所以试图推断它们的特性时有点怀疑 - 如果你关心的是将代码编译成汇编代码或机器代码并查看它是如何工作的在你的特定编译器上(对于特定的编译器命令行选项等)。如果您需要一个经验法则,则假定引用与指针具有相同的性能特征,除非分析或生成代码检查另有建议。

对于int你可以期望上面的第一个版本是没​​有比指针版本的比较慢,并且可能会更快,因为int参数可以从寄存器中传递和返回而没有需要一个内存地址。

如果/当/当通过指针版本是内联有更多的机会,有可能慢“需要一个内存地址,所以我们可以传递一个指针” /“不得不取消引用指针访问/更新值“的通用指针版本方面仍然可以优化掉了(如果你问的编译器试试),留下两个版本具有相同的性能....

,如果你需要问这样一个问题这个我无法想象你写的代码,其中这些都是重要的优化选择,所以更好的目标是做什么给你的客户端代码最干净,最直观,最强大的用法......现在 - 不管是x = f(x);(你可能会忘记领先的x =),或f(x)下,您可能没有意识到x可以修改,或f(&x)(其中有些来电者可能会认为他们可以通过nullptr是在自己的权利一个合理的问题,但是从你的性能问题分开。FWIW,C++ FAQ Lite建议引用这种情况的指针,但我个人拒绝它的推理和结论 - 这一切都归结为熟悉任何一种约定,以及您需要多长时间通过const指针值或指针值nullptr是一个有效的哨点,可能会与您的场景中所希望的您可能会修改我的含义混淆......这取决于您的编码风格,您使用的库,问题域等等。

+0

谢谢。我在应用程序的每一处传递了指针,但是我最近遇到了轻微的性能下降,并希望100%清除指针/引用,以及如何避免在函数调用过程中不惜一切代价复制变量。 – KKlouzal

+0

不客气。当你传递缓慢复制的大对象时,通过指针或引用传递可能会很有用,但是如果给定'int'不大并且可能比指针小,那么对'int'没有帮助。不妨尝试一下探查器(例如g ++/VC++包含内置探测器,ValGrind等) - 这可能会引发各种意想不到的事情,从而产生更大的差异。 –

您可以使用。函数调用的第一个原型是

DoSomething(&SomeInt); 

和第二架原型机

DoSomething(SomeInt); 

的你的例子都

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

能完成这个任务。在第一种情况 - 与指针 - 你需要调用函数DoSomething(&SomeInt);,在第二种情况下 - 参照 - 简单,因为DoSomething(SomeInt);

推荐的方法是,每当他们就能够使用引用和指针,只有当他们是必要。

+0

好的非常感谢你,最后一件事可以请你请参阅问题中的类示例? – KKlouzal

+0

@KKlouzal“如果我将一个整数传递给ChangeValue,那么当我在get中删除的整数将意味着当我尝试从类中使用MyInteger时,它将不再可用?” - 你不能“删除”一个整数。 MyInteger只是获得了新的价值,但稍后可以完美使用。 –

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

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

模式是,从调用中显而易见,myvariable可能会发生变化。

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

模式的优点是,在DoSomething的代码是有点清洁,DoSomething的具有较硬的时间来惹不好的方式来存储和你可能会得到更好的代码出来。缺点是从阅读调用中可以看出,myvariable可能会发生变化。

+0

如果你关心'myvariable'被改变,那么它应该已经是'const'。 –

+0

如果您遇到类似i = 0的情况, DoSomething的(I);我++;我不能成为常客,你是否非常关心我是否改变。 –

+0

所以只是不要那样做...你的代码被破坏了。当'i'不是'const'时,你将'i'传递给你不想修改'i'的函数。非常差的设计。 –