使用constness修改重载的成员运算符

时间:2011-12-13 15:10:04

标签: c++ operator-overloading const

以下是我的问题的概述: 我有一个名为TWMatrix的模板类。我重载了()运算符,以便它可以接受一对TWMatrix并提取相应的条目。我希望“提取”为2个不同的情况产生2个不同的结果。这在使用一对整数之前已经有效,但我很难让它为这个稍微不同的问题而工作:

  • 在一种情况下,我希望操作员将条目复制到另一个TWMatrix并输出。
  • 在另一种情况下,我希望操作员将这些条目的地址复制到TWDataPointer类型的对象中,输出该对象。

在第一种情况下,该方法不会破坏常量。实际上,条目本身既不会被修改也不会受到未来修改的影响。在后者中,重点是TWDataPointer对象可用于修改矩阵的那些条目。因此相应的代码位是:

TWDataPointer<T> operator () (const TWMatrix<int> & I1, const TWMatrix<int> & I2)
{
     return TWDataPointer<T>(*this,I1,I2);
}

TWMatrix<T> operator () (const TWMatrix<int> & I1, const TWMatrix<int> & I2) const 
{
    return SubMat(I1,I2);
}

SubMat是一种创建带有相应条目的矩阵的方法。它工作正常,它取得的价值在这里并不十分相关。问题是这个第二个运营商似乎永远不会被召唤。例如,如果,在我的主要内容中,我写道:

TWMatrix<double> test = D5(I1,I2);

编译器抱怨说:

error: conversion from ‘TWDataPointer<double>’ to non-scalar type ‘TWMatrix<double>’ requested

这非常不同:

T operator () (const int & i, const int & j) const 
{
    return data[j+i*nc];
}

T& operator () (const int & i, const int & j) 
{
    return data[j+i*nc];
}

与预期完全一致,并返回T或T&amp;视情况而定。根据我对重载运算符的理解,它是const,它允许编译器区分在哪种情况下使用哪个。那么为什么这不起作用?

提前感谢您的帮助,并随时要求您提供所需的任何额外代码。

PS:我已经考虑到了解决这个问题的方法,尽管它并不是非常丑陋,但它远没有那么简单,优雅和强大,如果我可以让它发挥作用。

编辑:感谢您的帮助到目前为止,我仍然期待着您的回答。特别是,我仍然对此感到困惑:

“回到int示例,为什么a = test(0,0)使用相应运算符的const版本,即使test没有声明为const?实际上,我已经检查过这是使用cout的情况两个版本的()运算符中的语句。“

3 个答案:

答案 0 :(得分:2)

是否有一个特定的原因,你需要只有一个const的第二种方法?从我在此代码中看到的内容以及可能的使用场景来看,虽然您的第二种方法在技术上是const方法,但 并未声明为。换句话说,它是一个可以被类实例的const和非const版本使用的方法,而且你很明显会遇到类实例需要方法的情况。一个const个对象。因此,使用将方法标记为const方法只是因为它不会更改调用方法的实例的状态并不意味着您必须将方法标记为const

为了使用这两种方案,我将生成两个版本的operator(),它们返回TWMatrix<T>类型...一个声明为const,另一个声明为constconst方法,以便const和非TWDataPointer<T>类实例都可以使用它。但缺点是您必须创建一个单独的方法来返回{{1}}类型,因为您不能仅基于返回类型进行重载。

答案 1 :(得分:1)

猜测,这是因为D5不是常数。它是该对象的cv资格,用于确定选择哪个运算符。

您似乎正在使用const资格来消除操作符的歧义。我会使用不同的技术(例如模板参数,它是您想要的输出类型,或模板参数是定义如何构造返回类型的策略,或者甚至更简单,指定您想要的输出参数)

答案 2 :(得分:0)

用于非静态成员函数。有一个隐含的对象参数 - this指针。如果非静态成员函数声明为const,则this指针将为const。实际上,你的两个函数看起来像是:

TWDataPointer<T> operator () (this, const TWMatrix<int> & I1, const TWMatrix<int> & I2)
{
     return TWDataPointer<T>(*this,I1,I2);
}

TWMatrix<T> operator () (const this, const TWMatrix<int> & I1, const TWMatrix<int> & I2) const 
{
    return SubMat(I1,I2);
}

我认为现在很明显,为什么当你的D5不是const时,第二个函数永远不会被调用。你可以使用

TWMatrix<T> matrix = ((const TWMatrix<T>&)D5)(I1,I2);

作为解决方法。但我认为这不是一个好主意。 const和非const方法获得不同的结果类型是非常棘手的。

对于你的int示例,如果测试不是const,我认为不会调用第一个函数。