我有几个纯虚拟类Matrix
和Vector
。在我的代码库中,我尝试只创建对它们的依赖,而不是它们的具体子类,例如SimpleTransformationMatrix44
和SimpleTranslationVector4
。这样做的动机是,我可以使用第三方(改编)课程代替我,而不会有太多麻烦。
我想重载算术运算符(源自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吗?有没有更好的方法来实现这一目标?
答案 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)
我是否因为这个想法而离开了阴谋?
是。解决此问题的适当方法是通过模板实现灵活性,而不是继承。继承绝对不适合这种问题。此外,通常(如果没有强制要求)将矢量或矩阵的尺寸另外指定为模板参数,而不是在运行时。