You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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对象,但当前的==运算符存在两个问题:

  1. 成员函数未声明为const,意味着它允许修改当前对象(this指针为COpFunc*),const对象无法调用非const成员函数
  2. 参数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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 21:50:40