在不分配新内存的情况下重载运算符*

Overload operator* without allocating new memory

我有 class foo 来管理固定长度的 vectorfloat 和一些元数据。我已经为 operator*:

实现了一个简单的重载
constexpr int numOfElements = 9;
class foo {
public:
    foo()
        : x(0), y(0), data(numOfElements)
    {}

    foo operator*(float value) {
        foo result;
        for (size_t k = 0; k < this->data.size(); ++k)
            result.data[k] = this->data[k] * value;
        return result;
    }

    int x;
    int y;
    std::vector<float> data;
};

以后我是这样使用的:

some_foo = *ptr_to_another_foo * 5;

其中 some_fooptr_to_another_foo 是在其他地方定义的,并包含一些值。这计算出正确的结果。但是,重载运算符中的 result foo 会创建另一个对象,这会导致内存分配由于性能原因而无法接受。由于 some_foo 已经为 data 分配了内存,是否有一种方法可以使用 some_foo.datas 内存而不是分配临时内存 foo result 来实现重载运算符]?

我总是可以实现类似 C 的基于指针的乘法函数,但我想在 C++ 中做一些更惯用的事情。

写一个 operator*= 将元素相乘:

foo& operator*=(float value) {
    for (size_t k = 0; k < this->data.size(); ++k)
        this->data[k] *= value;
    return *this;
}

如果稍后您意识到您确实还需要 operator*,您可以按照 operator*=:

来实现它
foo operator*(float value) const {
    foo result = *this;
    result *= value;
    return result;
}

注意operator*应该return一个新对象而不是修改this(它应该是一个const方法),而operator*=预计 return 对 *this 的引用(修改后)。如果要操作到位,最好使用复合*=.

不要return一个foo。相反,return 是一个包装器对象,它引用 *this 并且可以用作分配给另一个 foo 的操作数,用相乘的值改变它的状态。需要注意的是,如果引用的 foo 被销毁,returned 包装器将变得无效。

这个想法的通用模式称为表达式模板。这在线性代数库中很常用。