从抽象类中声明的重载算术运算符返回指针是否合理?

时间:2012-01-27 20:54:53

标签: c++ pointers operators overloading

我有几个纯虚拟类MatrixVector。在我的代码库中,我尝试只创建对它们的依赖,而不是它们的具体子类,例如SimpleTransformationMatrix44SimpleTranslationVector4。这样做的动机是,我可以使用第三方(改编)课程代替我,而不会有太多麻烦。

我想重载算术运算符(源自here):

T T::operator +(const T& b) const;
T T::operator -(const T& b) const;
T T::operator *(const T& b) const;

我想在纯虚拟类中声明它们,以便对它们的引用/指针执行操作是有效的,问题是不能通过值返回抽象类。我能想到的最佳解决方案是这样的:

std::unique_ptr<T> T::operator +(const T& b) const;
std::unique_ptr<T> T::operator -(const T& b) const;
std::unique_ptr<T> T::operator *(const T& b) const;

允许这样做(没有下线演员!):

std::unique_ptr<Matrix> exampleFunction(const Matrix& matrix1, const Matrix& matrix2)
{
    std::unique_ptr<Matrix> product = matrix1 * matrix2;
    return std::move(product);
}

在这种情况下,指针似乎是唯一的选项,因为返回一个值无效并返回一个引用只是愚蠢的。

所以我想我的问题是:我是否因为这个想法而离开了阴谋?如果你在一些你正在研究的代码中看到它,你会想到自己的WTF吗?有没有更好的方法来实现这一目标?

2 个答案:

答案 0 :(得分:1)

首先:重载运算符最适用于值类型。正如您所知,多态性并不能很好地发挥作用。如果你愿意拄着拐杖走路,这可能会有所帮助,但是:

如果您遵循Stackoverflow's operator overloading FAQ的建议,您将operator+()作为operator+=()的非成员实施。后者返回引用。它仍然是一个问题,因为它只能返回一个基类引用,但只要你只将它用于期望的表达式,你就可以了。

如果您再对operator+() as DeadMG suggested进行模板化,那么您可以按照自己的意愿行事:

template<typename T>
T operator+(const T lhs, const T& rhs)
{
  lhs += rhs;
  return lhs;
}

请注意,这会捕获任何T,但找不到更好匹配的operator+()重载。 (这似乎是一个好主意 - 直到你忘记包含一个标题,这个操作符捕获x+y,使代码编译,但默默地产生错误的结果。)所以你可能想要限制它。

一种方法是将它与矩阵和矢量类型放在同一名称空间中。或者您使用static_assert来确保只传递从这两个派生的类型。

答案 1 :(得分:0)

  

我是否因为这个想法而离开了阴谋?

是。解决此问题的适当方法是通过模板实现灵活性,而不是继承。继承绝对不适合这种问题。此外,通常(如果没有强制要求)将矢量或矩阵的尺寸另外指定为模板参数,而不是在运行时。