c++ - 复杂表达式中重载 + 的问题

标签 c++ operator-overloading operators

我有一个表示 3D vector 的类。它有一些成员函数(点积、叉积等)和一些重载运算符(+-*/)。我在复杂表达式中使用这些运算符时遇到问题。

在一个简化的测试用例中,如果我将运算符重载为

testclass operator+ (testclass& a, testclass& b) {
    return testclass(a.get()+b.get());
}

我可以

testclass a = testclass(3);
testclass b = testclass(4);
testclass c = a + b;

没有问题,但是表达式比较复杂

testclass c = a + b + a + b;

将无法编译。我可以通过将重载函数更改为

来解决问题
testclass operator+ (testclass a, testclass b) {
    return testclass(a.get()+b.get());
}

然而,这涉及按值传递,据我所知,在第一种情况下,这比按引用传递方案慢。我在一段数学密集型代码中使用此类,而我的真实类包含三个长 double 作为数据成员,因此我怀疑性能影响可能很大。

我的问题是:

  • 为什么会发生这种行为?
  • 我能否在不求助于按值传递的情况下避免它?
  • 当我有 3 个 long double 作为数据成员时,按值传递而不是按引用传递是否会影响性能?优化编译器 (g++ -O3) 会优化它吗?

提前致谢。

准确的编译错误是:

operator_overload.cpp: In function ‘int main()’:
operator_overload.cpp:37:29: error: no match for ‘operator+’ (operand types are ‘testclass’ and ‘testclass’)
         testclass c = a + b + a + b;
                             ^
operator_overload.cpp:37:29: note: candidate is:
operator_overload.cpp:30:15: note: testclass operator+(testclass&, testclass&)
     testclass operator+ (testclass& a, testclass& b) {
           ^
operator_overload.cpp:30:15: note:   no known conversion for argument 1 from ‘testclass’ to ‘testclass&’

我的完整测试代码如下:

#include <iostream>

class testclass {
public:
    testclass();
    testclass(int);
    int get();
    void set(int);
private:
    int data;
};

testclass::testclass() {
    data = 0;
}

testclass::testclass(int a) {
    data = a;
}

int testclass::get() {
    return data;
}

void testclass::set(int a) {
    data = a;
    return;
}

testclass operator+ (testclass& a, testclass& b) {
    return testclass(a.get()+b.get());
}

int main () {
    testclass a = testclass(3);
    testclass b = testclass(4);
    testclass c = a + b + a + b;
    std::cout << c.get() << std::endl;
    return 0;
}

最佳答案

问题是右值不能绑定(bind)到左值引用。 a + b + a + b 中的中间结果,比如说 a+b,是临时的,完整的表达式无法工作。 OTOH,const 引用可以绑定(bind)到右值。将签名改为testclass operator+ (const testclass& a, const testclass& b)即可解决。

要使上述签名有意义,您还需要让 testclass::get 成为 const 方法。

关于c++ - 复杂表达式中重载 + 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27630402/

相关文章:

C++ 不断收到错误 LNK2019 : unresolved external symbol

c++ - 无法创建 GLFW 窗口

c++ - 重载 << 使用模板 : Why am I getting the following error?

javascript - -~ 在 JavaScript 中做什么?

c++ - 标识符 "__builtin_expect"未定义(在 win 教程-谈话者示例中的 ROS 期间)

c++ - 资源对话框返回 -1

C++ : error: invalid operands of types ‘String*’ and ‘const char [7]’ to binary ‘operator+’

ruby - 在 Ruby 中覆盖实例变量数组的运算符

c# - 如何返回方法 C#

php - 3个不同的等于