按值传递/指针传递/引用澄清
Pass By Value/Pointer/Reference Clarification
我需要一次彻底澄清关于传递值/指针/引用的问题。
如果我有一个变量,比如
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,当我在get的删除中传递的整数将意味着当我试图从类内使用MyInteger它将不再是可用的?
感谢大家的时间,我知道这是一个基本的问题,但是我不断遇到的解释使我更加困惑。
从功能上讲,这三种方法都有效:
-
传递一个
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
本身就是一个合理的问题,但与你的性能问题分开。在这种情况下,c++ FAQ Lite推荐引用而不是指针,但我个人拒绝它的推理和结论——这一切都归结为对这两种惯例的熟悉程度,以及你需要传递const
指针值的频率,或者nullptr
是有效的指针值,这可能会与你的场景中希望的"你可以修改我"的含义混淆……这在很大程度上取决于你的编码风格、你使用的库、问题领域等。
你的两个例子
void DoSomething(int* Integer);
void DoSomething(int& Integer);
将完成任务。在第一种情况下-使用指针-您需要使用DoSomething(&SomeInt);
调用函数,在第二种情况下-使用引用-更简单,如DoSomething(SomeInt);
推荐的方法是只要引用足够就使用引用,而指针只在必要时使用。
两种都可以。第一个原型的函数调用将是
DoSomething(&SomeInt);
和第二个原型
DoSomething(SomeInt);
如前所述,您可以同时使用这两种方法。
的优点void DoSomething(int* Integer)
{
*Integer=0xDEADBEEF;
}
DoSomething(&myvariable);
模式是,从调用中可以明显地看出myvariable可能会发生变化。
void DoSomething(int& Integer)
{
Integer=0xDEADBEEF;
}
DoSomething(myvariable);
模式的优点是DoSomething中的代码更简洁,DoSomething很难以不好的方式扰乱内存,你可能会从中得到更好的代码。缺点是从读取调用中不能立即看出myvariable可能被更改。
- C++取消引用指针.为什么会发生变化
- 深层复制具有自引用指针的类
- Visual c ++,使用字符串引用/指针调用 dll 函数
- std::unordered_map::提取引用/指针失效
- 为什么在引用指针时将 const 放在 & 符号的左侧有效,而在右侧则无效?
- 区分接受常量参数的函数引用/指针和与函数参数同名的非常量参数
- 如何在 c++ 中使用带有数学运算的引用/指针?
- 了解通过引用传递取消引用指针时C++堆/堆栈分配
- 取消引用指针并立即为其分配变量,导致分段错误
- 如何获取指向类(而不是对象)的引用/指针
- 将类型参数传递给自引用指针
- 我应该如何定义返回指针的函数?(引用指针与指针指针)
- 在析构函数内取消引用指针时出现分段错误
- 来自引用指针的内存泄漏
- 引用指针后面的值
- 无法取消引用指针
- 引用指针调用成员函数
- 未定义的引用指针的变量模板在clang中功能,而不是GCC
- 取消引用指针以创建数组的副本
- 有关启动引用指针的引用的问题