草庐IT

c++ - 有没有办法在函数调用中通过引用传递和通过值显式传递?

coder 2023-05-31 原文

如果您要查看这段代码,

int x = 0;
function(x);
std::cout << x << '\n';

您将无法通过任何语法方式验证参数 x 是通过引用传递还是通过值传递。您确定的唯一方法是查看函数声明或函数定义。

这是一个简单的例子,说明我认为这可能是一个问题:

std::string Lowercase(std::string str); //<- this is hidden away in code; probably in a different file.

int main(){
    std::string str = "HELLO";
    Lowercase(str);
    std::cout << str << '\n'; //<- Bug! we expected to output "hello".  The problem is not very easy to spot, especially when a function name sounds as though it will change the passed in value.
}

为了避免在函数调用和函数声明(或在某些情况下,文档)之间跳转以了解函数行为,有没有办法在函数调用的语法中显式记录参数预计会改变(即引用参数)或正在发送拷贝(即按值传递)?

我意识到也可以选择通过 const& 传递,这与传递值的概念相似,因为传入的变量在函数调用后不会改变其值。


我确信该语言中存在各种可能会增加理解参数传递方式的复杂性的情况 - 但我很好奇,有没有办法以我想要的方式解决这个问题?

我注意到有些人编写了两个相似的函数。其中一个采用值参数,另一个采用指针。这允许调用这样的函数:

Lowercase(str); //we assume the value will not change
Lowercase(&str); //we assume the value will change

但是这个解决方案还有很多其他问题,我不想失去引用的好处。此外,我们仍在对行为做出假设。

最佳答案

有些人坚持认为传递可变对象的正确方法是使用指针。也就是说,你会通过

Lowercase(&str);

... 和 Lowercase() 显然会被实现为采用指针。这种方法可能适合您的需求。

然而,我想提一下,这不是我会做的!相反,我喜欢的方法是使用适当的名称。例如,

inplace_lowercase(str);

几乎说它要做什么。显然,inplace_lowercase() 实际上是一种算法,并且可以合理地称为

inplace_lowercase(str.begin() + 1, str.end());

也是。

以下是我不喜欢通过指针传递参数和/或为什么我不相信参数是如何传递的明确指示的一些原因:

  • 指针可以为空。在我看来,一个强制性的引用参数应该是一个引用。
  • 通过指针传递仍然不能表明参数是否可以修改,因为参数可能是 T const*
  • 拥有有意义的名称实际上更容易理解到底发生了什么。
  • 在没有查阅其文档和/或知道被调用函数将做什么的情况下调用某项内容无论如何都不起作用,并指出事情是如何传递的,这是试图解决更深层次问题的症状。

关于c++ - 有没有办法在函数调用中通过引用传递和通过值显式传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19800841/

有关c++ - 有没有办法在函数调用中通过引用传递和通过值显式传递?的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  3. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  4. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  5. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  6. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  7. ruby-on-rails - 有没有办法为 CarrierWave/Fog 设置上传进度指示器? - 2

    我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r

  8. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  9. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  10. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

随机推荐