Win32中CList为何无法识别自定义类的==运算符?
问题分析与修复:CList::Find()调用时的==运算符错误
问题背景
定义COpFunc类并实现==运算符后,基于MFC的CList模板创建列表并添加实例,普通的==运算测试正常,但调用CList::Find()时编译器报错:
error C2678: binary == : no operator found which takes a left-hand operand of type const COpFunc (or there is no acceptable conversion)
用户怀疑错误与this指针有关,但不清楚具体修复方式。
原代码
#include "stdafx.h" #include <stdint.h> /////////////////////////////////////////////// // Define a class with a constructor, two // data members, and a == operator // class COpFunc { public: COpFunc(); COpFunc( uint32_t opAddr, char opFlag ); uint32_t addr; char allocFlag; BOOL operator == ( COpFunc& f2 ) { return ( this->addr == f2.addr ) && ( this->allocFlag == f2.allocFlag ); } }; COpFunc::COpFunc( uint32_t opAddr, char opFlag ) { addr = opAddr; allocFlag = opFlag; }; COpFunc::COpFunc() { }; /////////////////////////////////////////////// // Define a list of the COpFunc class // CList<COpFunc,COpFunc&> ops; int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { HMODULE hModule = ::GetModuleHandle(NULL); POSITION pos; COpFunc temp; if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0)) return 1; /////////////////////////////////////////////// // Create two instances of COpFunc // COpFunc t1( 0x1000, 'a' ); COpFunc t2( 0x1000, 'a' ); /////////////////////////////////////////////// // Test the == operator // if( t1 == t2 ) TRACE( "Test 1\n" ); // yep... t1.addr = 0x2000; if( t1 == t2 ) // nope... TRACE( "Test 2\n" ); /////////////////////////////////////////////// // Add the instances to the list // ops.AddTail( t1 ); ops.AddTail( t2 ); /////////////////////////////////////////////// // Dump the list // pos = ops.GetHeadPosition(); while( NULL != pos ) { temp = ops.GetNext( pos ); TRACE( "func: %08x %c\n", temp.addr, temp.allocFlag ); } /////////////////////////////////////////////// // Farkle // // pos = ops.Find( t1 ); return 0; }
问题原因
CList::Find()在执行比较时,会将列表中的元素视为const对象,但当前的==运算符存在两个问题:
- 成员函数未声明为
const,意味着它允许修改当前对象(this指针为COpFunc*),const对象无法调用非const成员函数 - 参数
f2是普通引用而非const引用,无法接收const对象作为实参
修复方案
修改COpFunc类中的==运算符,将其声明为const成员函数,并把参数改为const引用:
BOOL operator == (const COpFunc& f2) const { return (this->addr == f2.addr) && (this->allocFlag == f2.allocFlag); }
关键修改说明
- 给参数
f2添加const修饰:保证运算符不会修改传入的对象,同时允许接收const对象作为参数 - 在函数末尾添加
const:声明该成员函数不会修改当前对象(此时this指针变为const COpFunc*),让const对象可以调用该运算符
修改后,取消pos = ops.Find( t1 );的注释,即可正常编译运行。
内容的提问来源于stack exchange,提问作者Fred W
相关产品推荐
相关产品推荐

