为什么这个程序员特别通过引用在函数中传递指针?
Why does this programmer in particular passes pointers in functions by reference?
我看到了这个特殊的代码:
void GetMe(User& user) {
std::cout << user.getName() << std::endl;
}
main(...) {
User* user = new User("Joe");
GetMe(*user);
getchar();
return EXIT_SUCCESS;
}
我找不到一个例子,特别是在堆栈溢出的任何问题上,只有一些(&*)而不是(&),我不明白它背后的意义是什么,它是为了安全,以防指针在其他地方被删除?(这是一个多线程应用程序)
当您将用户定义的类型传递给函数时,您可以使用以下方法之一:
-
按值传递:
void GetMe(User user) { ... }
-
通过指针传递:
void GetMe(User* userPtr) { ... } void GetMe(User const* userPtr) { ... }
-
通过引用:
void GetMe(User& user) { ... } void GetMe(User const& userPtr) { ... }
根据经验,按引用传递比按值传递或按指针传递更可取。
通过引用传递而不是通过值传递,可以避免复制对象的成本。
当你传递指针时,你不能假设nullptr
不会被传递。所以,你要在GetMe
中添加检查来解释这种情况。当你通过引用传递时,你就不用担心了。
我相信你是在问为什么代码不写成:
void GetMe(User* user) {
std::cout << user->getName() << std::endl;
}
main(...) {
User* user = new User("Joe");
GetMe(user);
getchar();
return EXIT_SUCCESS;
}
但是很多有经验的程序员反而会问为什么它不是。
void GetMe(User const& user) {
std::cout << user.getName() << std::endl;
}
main(...) {
User* user = new User("Joe");
GetMe(*user);
getchar();
return EXIT_SUCCESS;
}
在这两个例子中,我忽略了更严重的内存泄漏非智能指针问题,而只关注如何将user传递给GetMe。
我认为你问的这个问题很大程度上是一个风格问题。我没有看到多线程或其他功能上的差异(正如你所问的),也没有强烈的理由支持这两种风格。
但我确实看到了标记它const
时,无论是通过指针或引用传递强有力的论据。如果getName()
不是const
(导致更难使用户const),那么可能也应该修复。
在我看来,你的问题有两个部分:
-
为什么是
void GetMe(User& user) { }
而不是void GetMe(User* user) {}
?可能有以下几个原因:void GetMe(User& user) { }
意味着一个可伸缩的非空输入和输出user
。如果您想要不可延展性或只能输入,请使用void GetMe(User const& user) { }
。如果你想要空的,使用指针等…
在c++中传递参数的方式有非常具体的语义,所以你必须非常小心。它们都有不同的含义:通过引用传递,通过指针传递,通过const引用传递,通过const指针传递,等等……
- 为什么用
User* user = new User("Joe");
代替User user("Joe");
?您希望在堆上动态分配内存,而不是在堆栈上本地分配内存,这可能是有原因的。例如,如果您希望对象的生存期比右括号长。另一个原因是,如果User
是一个非常大的对象,那么您希望它在堆上(对于现代cpu,这可能不是一个问题)。
注意多线程是一个完全不同的问题。你必须担心内存可见性、同步、互斥、竞争条件等... ...这些问题大多与上述两点是正交的。如果你不想浪费大量的时间来调试线程问题,我建议你在走上这条路之前掌握好基本的c++语义。
默认情况下,参数按值传递给函数,即不带&,你在函数中有一个参数的副本——只是它的值的副本,而不是它的引用——也就是说,你在函数中没有真正的参数,如果你必须对参数的地址(引用)做一些操作,一切都会出错。
考虑这个例子:一个函数不能分配内存给它的形参(char):
void al(char * c) //wrong way: pass by value
{
c =new char[10];
}
main()
{
char * x;
al(x);//don't allocated because pass by value/.
*x='a';//memory error//
}
但是这个函数声明可以这样做,因为通过引用传递:
void al(char * & c)
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针