C++ 没有新返回对象的算术运算符

C++ Arithmetic Operator without new return object

本文关键字:对象 运算符 返回 新返回 C++      更新时间:2023-10-16
这是一个

相当简单的概念。我有一个算术运算符,我希望操作更新而不是创建对象。本质上

MyType A;
MyType B;
MyType C;
A = B - C;
A = C - B;

语句A = B - C不应该再次调用 MyType 的构造函数,因为 A 已经创建,即构造函数应该只在这个程序中调用 3 次。有没有办法在保持良好语法的同时实现这一目标?我怀疑我可以让运算符函数知道不要创建对象,而是使用一些引用。有没有一种更简化的方法可以使用一些我不知道的 c++ 语法来做到这一点?

class MyType
{
    MyType* OperatorReturnObj;
    MyType operator-(const MyType& Left, const MyType& Right)
    {
        // This removed and replaced with SetOperatorReturnObj function
        // MyType OperatorReturnObj();
        OperatorReturnObj= Left - Right;
        return OperatorReturnObj;
    }

    void MyType SetOperatorReturnObj(MyType* Ref)
    {
         OperatorReturnObj = Ref;
    }
};

如果没有丑陋的技巧,例如创建对象池并在内部使用它们(在这种情况下,复杂性将比任何好处都更昂贵),就没有办法实现这一目标。问题是那句话:

A = B - C;

等于:

A.operator=( operator-( B, C ) );

如您所见operator-( B, C )必须首先执行并在某处提供结果。因此,您必须更改语法,例如:

A += B; A -= C; // or even
(A += B) -= C; // or maybe
A += B -= C; 

或者使用常规语法,如果需要效率,请实现移动语义。

经过一番思考,您可以创建类型为 MyTypeExression 的对象,该对象不执行实际计算,但会记住参数和操作,并且仅在稍后执行MyType::operator=(MyTypeExression)时执行。尽管要使其正常工作,您可能需要一个带有智能指针的包装器MyType这样MyTypeExression就不必复制它的参数。因此,此解决方案可以被认为是我之前提到的复杂技巧。

我希望操作更新而不是创建对象

对于A = B - C;Aoperator= 更新

更具体地说,operator-的返回值是按值传递的,则必须在operator-内部创建一个临时变量,然后复制/移动到A

BTW1:OperatorReturnObj= Left - Right;将导致无限递归。

BTW2:MyType A();确实是一个函数声明。最令人烦恼的解析

你不能

在 A = B - C 中,首先计算 B - C 表达式。然后将结果复制到 A。B - C 表达式对 A 一无所知,因此无法直接更新 A。您可以重载赋值运算符,但这不会阻止创建新对象。

一些提示:

首先,您没有指定如何初始化内部指针属性,因此此时它指向内存堆栈中未指定的值。

其次,operator-方法(!)的定义不像你那样。 看看"二进制算术运算符"二进制运算符必须返回对从中调用它们的对象的引用。

第三,对象本身"自动"传递给其方法,并可用作this指针。因此,您不必将其作为第一个参数传递。最后,要返回引用,您必须返回值,而不是指针:--> *this

因此,像 A=B+C 这样的表达式的计算结果为:

A.operator=(B.operator+(C))

所以 B+C 与 C+B 不同(我在这里不输入继承的细节。

灵感来自上面相同的上一个链接:

class X {
    int internalprivatevalue;
    //.... 
public:
    X& operator+(const X& second) {
        // actual addition of second to *this takes place here
        // e.g. internalprivatevalue+=second. internalprivatevalue;
        return *this; // return the result by reference!! 
    }

}

希望能澄清更多的疑虑。