使用constness修改重载成员操作符
Modifying overloaded member operator using constness
我的问题概述如下:我有一个名为TWMatrix的模板化类。我已经重载了()运算符,这样它就可以接受一对TWMatrix并提取相应的条目。我希望"提取"在两个不同的情况下产生两个不同的结果。当取一对int型时,这之前已经工作了,但是对于这个稍微不同的问题,我很难让它工作:
- 在一种情况下,我希望操作符将条目复制到另一个TWMatrix中并输出。
- 在另一种情况下,我希望操作符将这些条目的地址复制到TWDataPointer类型的对象中,并输出该对象。
在第一种情况下,该方法不破坏constness。事实上,这些条目本身既没有被修改,也不会受到将来修改的影响。在后一种情况下,关键在于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是一个创建具有相应条目的矩阵的方法。它工作得很好,它获取的值在这里不是很重要。问题是,第二个操作符似乎永远不会被调用。例如,在main中,我写:
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&视情况而定。从我对重载操作符的理解来看,是const让编译器区分在什么情况下使用哪个操作符。那么,为什么这行不通呢?
提前感谢您的帮助,并随时要求您可能需要的任何额外的代码片段。
PS:我已经有了一个解决这个问题的方法,虽然它不是非常丑陋,但它远没有这样简单,优雅和健壮,如果我能让它工作的话。
谢谢到目前为止的帮助,我仍然期待听到你的答案。特别是,我仍然对这个感到困惑:"回到int的例子,为什么a = test(0,0)使用相应操作符的const版本,即使test没有声明为const?实际上,我在两个版本的()操作符中使用cout语句检查了这种情况。"
是否有一个特定的原因,您只需要第二个方法的单个const
?从这段代码和可能的使用场景来看,虽然您的第二个方法在技术上是const
方法,但它没有要这样声明。换句话说,它是一个可以被const
和非const
版本的类实例使用的方法,你显然会遇到这样的情况,你的类实例需要的方法,当它不是一个const
对象。因此,将方法标记为const
方法只是因为它不会改变调用该方法的实例的状态,并不意味着您必须将方法标记为const
。
为了处理这两种情况,我将生成两个版本的operator()
,返回TWMatrix<T>
类型…一个被声明为const
,另一个被声明为非const
方法,以便const
和非const
类实例都可以使用它。缺点是你必须创建一个单独的方法来返回TWDataPointer<T>
类型,因为你不能仅仅基于返回类型重载。
猜测,这是因为D5
不是常数。该对象的cv-限定符决定选择哪个操作符。
看起来您正在使用const
限定符来消除运算符的歧义。我会使用一种不同的技术(例如,模板参数是你想要的输出类型,或者模板参数是定义如何构造返回类型的策略,或者更简单,指定你想要的输出参数)
用于非静态成员函数。有一个隐含的对象参数——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,我不认为第一个函数会被调用
- 带引用类成员的赋值操作符
- 通过自增操作符访问类成员
- 用于具有const数据成员的类的move和右值赋值操作符
- 使用constness修改重载成员操作符
- 私有内部成员的操作符重载
- 在操作符[]前解引用成员指针
- 解引用操作符(*)作为类的成员函数重载时是如何工作的?
- c++操作符=类成员中有互斥对象
- c++的另一个类成员和重载操作符
- 双(?)定义模板成员操作符
- 为具有引用成员变量的类创建赋值操作符
- 在复制赋值操作符中赋值基类成员
- 从模板化的类赋值操作符访问私有成员变量
- 在静态成员数组定义中对自身使用sizeof操作符
- 为什么c++中的成员函数在对象名后用点操作符访问?
- 从成员函数调用重载操作符(静态)
- 如何检查成员操作符(类型)
- 指向成员操作符的指针
- 用int成员实现哪些操作符
- 如何处理赋值操作符和复制构造函数中的引用数据成员