2012-01-27 33 views
2

我有几个纯虚类,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?有没有更好的方法来实现这一目标?

回答

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; 
} 

注意,这会赶上对于没有更好的匹配operator+()过载可以找到的任何T。 (这可能看起来是一个好主意 - 直到你忘记包含头部并且该操作符捕获了x+y,使得代码编译,但是默默地产生了错误的结果。)所以你可能想限制这个。

一种方法是把它放到同一个命名空间,你矩阵与向量类型。或者,您使用static_assert来确保仅传入来自两者的类型。

+0

对于迟到的重播,我沉迷了一段时间。我不确定我是否有模板化的'operator +()'(我没有意识到那是DeadMG所说的),因为你说的原因。我想我只会使用常规方法而不是运算符,这样我就不会破坏重载约定。谢谢! – 2012-03-03 22:00:53

0

有我关闭了这个想法的情节?

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

+0

'Matrix'和'Vector'实际上是模板,但是我留下了那些细节以使我的示例更简单。他们将数据类型(例如float)和大小作为模板参数。我倾向于改变'矩阵'来采取维度。我如何通过模板实现灵活性? – 2012-01-27 21:18:24