jjzjj

c++ - 编码练习 : return by value or by reference in Matrix multiplication?

coder 2024-02-26 原文

我正在引用 this one 写这个问题我昨天写的。在一些文档之后,我似乎很清楚我想做的事情(以及我认为可能的事情)几乎是不可能的,如果不是根本不可能的话。有几种实现它的方法,由于我不是经验丰富的程序员,我问你会选择哪一种。我再次解释了我的问题,但现在我有一些解决方案可以探索。

我需要什么

我有一个 Matrix 类,我想实现矩阵之间的乘法,这样类的使用非常直观:

Matrix a(5,2);
a(4,1) = 6 ;
a(3,1) = 9.4 ;           
...                   // And so on ...

Matrix b(2,9);
b(0,2) = 3;
...                   // And so on ...

// After a while
Matrix i = a * b;

我昨天有什么

此刻我重载了两个运算符 operator*operator= 直到昨天晚上它们都是这样定义的:

Matrix& operator*(Matrix& m);
Matrix& operator=(Matrix& m);

operator* 在堆上实例化一个新的 Matrix 对象(Matrix return = new Matrix(...)),设置值,然后:

return *result;

今天的我

discussion之后我决定以一种“不同的方式”来实现它,以避免用户被任何类型的指针打扰并保持用法不变。 “不同的方式”是按值传递 operator* 的返回值:

Matrix operator*(Matrix& m);
Matrix& operator=(Matrix& m);

运算符*在堆栈上实例化return,设置值然后返回对象。

这种方法有一个问题:它不起作用。 operator= 需要一个 Matrix& 而 operator* 返回一个 Matrix。此外,由于另一个原因,这种方法对我来说不太好:我正在处理矩阵,它可能非常大,这个库的目标是 1)对我的项目足够好 2)快速,所以可能通过按值(value)不应该是一个选项。

我探索过哪些解决方案

嗯,按照前面的建议discussion我读了一些关于智能指针的东西,它们看起来不错,但我仍然不知道如何用它们解决我的问题。它们处理内存释放和指针复制,但我基本上使用的是引用,所以它们对我来说看起来不是正确的选择。但我可能错了。

也许唯一的解决办法就是按值传递,也许我不能兼顾效率和良好的接口(interface)。但同样,您是专家,我想知道您的意见。

最佳答案

您遇到的问题是表达式 a * b 创建了一个 temporary 对象,而在 C++ 中,临时对象不允许绑定(bind)到非常量引用,这是您的 Matrix& operator=(Matrix& m) 所采用的。如果将其更改为:

Matrix& operator=(Matrix const& m);

代码现在应该可以编译了。除了生成可编译代码的明显好处 :),添加 const 还可以告诉调用者您不会修改参数 m,这可能是有用的信息.

你也应该为你的 operator*() 做同样的事情:

Matrix operator*(Matrix const& m) const;

[编辑: 末尾附加的 const 表示该方法 promise 不会更改 *this乘法的左侧,要么。这是处理诸如 a * b * c 之类的表达式所必需的——子表达式 a * b 创建一个临时的,并且在没有 const<> 最后。感谢 Greg Rogers 在评论中指出这一点。]

附言C++ 不允许临时对象绑定(bind)到非常量引用的原因是因为临时对象(顾名思义)只存在很短的时间,而且在大多数情况下,试图修改它们是错误的。

关于c++ - 编码练习 : return by value or by reference in Matrix multiplication?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/477452/

有关c++ - 编码练习 : return by value or by reference in Matrix multiplication?的更多相关文章

  1. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  2. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

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

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

  4. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  5. 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.你能做的最好的事情是:

  6. 牛客网专项练习30天Pytnon篇第02天 - 2

    1.在Python3中,下列关于数学运算结果正确的是:(B)a=10b=3print(a//b)print(a%b)print(a/b)A.3,3,3.3333...B.3,1,3.3333...C.3.3333...,3.3333...,3D.3.3333...,1,3.3333...解析:    在Python中,//表示地板除(向下取整),%表示取余,/表示除(Python2向下取整返回3)2.如下程序Python2会打印多少个数:(D)k=1000whilek>1:    print(k)k=k/2A.1000 B.10C.11D.9解析:    按照题意每次循环K/2,直到K值小于等

  7. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  8. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  9. c - Ruby - 源代码 - 编码风格 - 2

    查看Ruby代码,它具有以下proc_arity:staticVALUEproc_arity(VALUEself){intarity=rb_proc_arity(self);returnINT2FIX(arity);}更多的是C编码风格问题,但为什么staticVALUE在单独的一行而不是像这样的:staticVALUEproc_arity(VALUEself) 最佳答案 它来自UNIX世界,因为它有助于轻松grep函数的定义:$grep-n'^proc_arity'*.c或使用vim:/^proc_arity

  10. ruby - 如何以编程方式删除实例上的 "singleton information"以使其编码(marshal)? - 2

    我创建了一个由于“在运行时执行的单例元类定义”而无法编码的对象(这段代码的描述是否正确?)。这是通过以下代码执行的:#defineclassXthatmyusesingletonclassmetaprogrammingfeatures#throughcallofmethod:break_marshalling!classXdefbreak_marshalling!meta_class=class我该怎么做才能使对象编码正确?是否可以从对象instance_of_x的classX中“移除”单例组件?我真的需要一个建议,因为我们的一些对象需要通过Marshal.dump序列化机制进行缓存。

随机推荐