我看到了这个特殊代码:
void GetMe(User& user) {
std::cout << user.getName() << std::endl;
}
main(...) {
User* user = new User("Joe");
GetMe(*user);
getchar();
return EXIT_SUCCESS;
}
我找不到这方面的例子特别是关于Stack溢出的任何问题只有一些用(&amp; *)而不是(&amp;)而且我不明白它背后的意义是什么,是为了安全以防指针在其他地方被删除? (这是一个多线程的应用程序)
答案 0 :(得分:1)
将用户定义的类型传递给函数时,可以使用以下方法之一:
按值传递:
void GetMe(User user) { ... }
通过指针:
void GetMe(User* userPtr) { ... }
void GetMe(User const* userPtr) { ... }
通过引用传递:
void GetMe(User& user) { ... }
void GetMe(User const& userPtr) { ... }
根据经验,通过引用传递比传递值或通过指针更好。
当您通过引用而不是值传递时,将避免复制对象的成本。
当你通过指针时,你不能假设不会传递nullptr
。因此,您已在GetMe
中添加检查以说明该情况。当你通过引用传递时,你不必担心。
答案 1 :(得分:0)
我相信你在问为什么代码没有写成:
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;
}
在这两个例子中,我忽略了更严重的内存泄漏非智能指针问题,只是看看用户如何传递给GetMe。
原始与我认为你问的方式主要是一个风格问题。我没有看到多线程或其他功能差异(正如你所问的那样),也没有看到任何一种风格的强烈论据。
但是我确实看到了在通过指针或引用传递时标记它const
的强大论据。如果getName()
不是const
(导致用户更难以使用),则可能也应该修复。
答案 2 :(得分:0)
在我看来,你的问题分为两部分:
为什么界面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 ++语义。
答案 3 :(得分:-2)
默认情况下,参数按值传递给函数,即没有&amp; ,你有一个函数的副本 - 只是复制它的值,而不是它的参考 - 即你没有在函数中有你的真实参数,如果你必须用参数的地址(参考)做一些操作,一切都会出错。
考虑这个例子:一个无法为其参数(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)