我正在写,参照这个问题这一个,我昨天写.经过一些文档记录后,我觉得我想做的事情(以及我认为可行的事情)几乎是不可能的,如果不是不可能的话.有几种方法可以实现它,因为我不是一个经验丰富的程序员,我问你会选择哪种方式.我再次解释我的问题,但现在我有一些解决方案需要探索.
我需要的
我有一个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 return = new Matrix(...)
在堆上实例化一个新的Matrix对象(),设置值,然后只需:
return *result;
我今天拥有的
在讨论之后,我决定以"不同的方式"实现它,以避免用户被任何类型的指针打扰并保持使用不变."不同的方式"是通过值传递operator*的返回值:
Matrix operator*(Matrix& m); Matrix& operator=(Matrix& m);
operator*return
在堆栈上实例化,设置值然后返回对象.
这种方法存在问题:它不起作用.operator =期望Matrix&和operator*返回一个Matrix.此外,这种方法对我来说看起来并不那么好,原因是另一个原因:我正在处理矩阵,这可能非常大,而且这个库的目标是1)对我的项目来说足够好2)快,所以可能通过按价值不应该是一种选择.
我探讨了哪些解决方案
好吧,按照前面讨论中的建议,我读了一些关于智能指针的内容,它们看起来很棒,但我仍然无法弄清楚如何用它们来解决我的问题.他们处理内存释放和指针复制,但我基本上使用引用,所以他们看起来不适合我.但我可能错了.
也许唯一的解决方案是传递价值,也许我无法获得效率和良好的界面.但同样,你是专家,我想知道你的意见.
您遇到的问题是表达式a * b
创建了一个临时对象,而在C++中,不允许临时绑定到非常量引用,这就是您所Matrix& operator=(Matrix& m)
需要的.如果您将其更改为:
Matrix& operator=(Matrix const& m);
代码现在应该编译.除了生成可编译代码:)的明显好处之外,添加const
还会向您的调用者传达您不会修改参数的信息m
,这可能是有用的信息.
您也应该为您做同样的事情operator*()
:
Matrix operator*(Matrix const& m) const;
[编辑:最后的附加const
表示该方法承诺不会改变*this
,乘法左侧的对象也是如此.这对于处理诸如以下a * b * c
的表达式是必要的- 子表达式a * b
创建一个临时表达式,并且const
在没有结束时不会绑定.感谢格雷格罗杰斯在评论中指出这一点.]
PS C++不允许临时绑定到非常量引用的原因是因为临时存在(顾名思义)只有很短的时间,并且在大多数情况下,尝试修改它们是错误的.
您应该阅读Scott Meyers的Effective C++,它有很多主题.前面已经说过,最好的签名operator=
和operator*
有
Matrix& operator=(Matrix const& m); Matrix operator*(Matrix const& m) const;
但我不得不说你应该实现乘法代码
Matrix& operator*=(Matrix const& m);
并重新使用它 operator*
Matrix operator*(Matrix const &m) const { return Matrix(*this) *= m; }
这样,用户可以在不想创建新矩阵的情况下成倍增加.当然这个代码工作你也应该有复制构造函数:)