none
Sobrecarga operador == RRS feed

  • Pregunta

  • Me gustaría saber como puedo sobrecargar el operador de igualdad para la clase Employee  en Visual C++.


    public ref class Employee{
    	public:		
    		property _int32 Id;
    		property _int32 Age;
    		property String^ Cuil;
    		property String^ FirstName;
    		property String^ LastName;
    		property String^ Email;
    };
    Muchas gracias!!!
    martes, 12 de junio de 2012 15:39

Respuestas

  • Muchas gracias por tu respuesta, pero no me funcionó. La solución que me dió, es "copiar" la forma de sobrecargar el operador, de la forma que lo haría en C#. El código escrito es el siguiente:

    FakeCompany.Entities.Employee.h file

    // FakeCompany.Entities.h
    
    #pragma once
    
    using namespace System;
    using namespace System::Collections::Generic;
    
    namespace FakeCompany{
    	namespace Entities {
    
    		public ref class Employee: public IEquatable<Employee^>{
    	public:		
    		property _int32 Id;
    		property _int32 Age;
    		property String^ Cuil;
    		property String^ FirstName;
    		property String^ LastName;
    		property String^ Email;
    
    		bool static operator==(Employee^ a, Employee^ b);
    		bool static operator!=(Employee^ a, Employee^ b);
    
    		virtual bool Equals(Employee^ other);
    		virtual bool Equals( Object^ obj) override;
    		virtual _int32 GetHashCode() override;
    
    	};
    	}
    }


    FakeCompany.Entities.Employee.cpp file

    // This is the main DLL file.
    
    #include "stdafx.h"
    
    #include "FakeCompany.Entities.Employee.h"
    
    
    bool FakeCompany::Entities::Employee::Equals(Employee^ other)
    {
    	return other != nullptr
    		&& this->Id == other->Id
    		&& this->Age == other->Age
    		&& this->Cuil == other->Cuil
    		&& this->FirstName == other->FirstName
    		&& this->LastName == other->LastName
    		&& this->Email == other->Email;
    }
    
    bool FakeCompany::Entities::Employee::Equals(Object^ obj) 
    {		
    	return obj != nullptr
                && (obj->GetType() == Employee::typeid)
                && this->Equals(dynamic_cast<Employee^>(obj));
    }
    
    _int32 FakeCompany::Entities::Employee::GetHashCode()
    {
    	_int64 hash = 17;	
    
    	hash *= 23 + this->Id.GetHashCode();
    	hash *= 23 + this->Age.GetHashCode();
    	hash *= 23 + this->Cuil == nullptr ? 0 : this->Cuil->GetHashCode();
    	hash *= 23 + this->FirstName == nullptr ? 0 : this->FirstName->GetHashCode();
    	hash *= 23 + this->LastName == nullptr ? 0 : this->LastName->GetHashCode();
    	hash *= 23 + this->Email == nullptr ? 0 : this->Email->GetHashCode();
    
    	return (hash > _int32::MaxValue) ? _int32::MaxValue : hash;
    }
    
    
    bool FakeCompany::Entities::Employee::operator==(Employee^ a, Employee^ b)
    {
    	return Object::ReferenceEquals(a, nullptr)
                    && Object::ReferenceEquals(b, nullptr)
                    || Employee::Equals(a, b);
    }
    
    
    
    bool FakeCompany::Entities::Employee::operator!=(Employee^ a, Employee^ b)
    {
    	return !(a == b);
    }

    Saludos!!!


    • Editado Augusto Pedraza miércoles, 13 de junio de 2012 17:07 Correción código
    • Marcado como respuesta Augusto Pedraza miércoles, 13 de junio de 2012 17:08
    miércoles, 13 de junio de 2012 17:06

Todas las respuestas

  • Antes de nada tienes que decidir cuando dos Employee son iguales y después decirselo al compilador.

    ¿Es el mismo Employee si tienen el mismo Id? Entonces simplemente:

    bool operator==(const Employee &Otro) const {
      return Id==Otro.Id;
      }
    	
    

    ¿Es el mismo Employee si tiene igual los otros campos aunque varie el Id? (Para comprobar que no haya un mismo empleado con dos Id) Entonces tienes que comprobar todos los otros datos sin comprobar el Id. Te lo dejo como ejercicio.

    Ten en cuenta que al comprobar los Strings sería recomendable 'normalizarlos' quitando blancos duplicados pasando todas las letras a minúsculas (o mayúsculas) y quitando acentos para que nadie haga 'trampas' y que "Juan José" == "JUAN JOSE" == "   Juan Jose" == "Juan    José" por poner algunos ejemplos que se me ocurren.

    martes, 12 de junio de 2012 21:23
  • Muchas gracias por tu respuesta, pero no me funcionó. La solución que me dió, es "copiar" la forma de sobrecargar el operador, de la forma que lo haría en C#. El código escrito es el siguiente:

    FakeCompany.Entities.Employee.h file

    // FakeCompany.Entities.h
    
    #pragma once
    
    using namespace System;
    using namespace System::Collections::Generic;
    
    namespace FakeCompany{
    	namespace Entities {
    
    		public ref class Employee: public IEquatable<Employee^>{
    	public:		
    		property _int32 Id;
    		property _int32 Age;
    		property String^ Cuil;
    		property String^ FirstName;
    		property String^ LastName;
    		property String^ Email;
    
    		bool static operator==(Employee^ a, Employee^ b);
    		bool static operator!=(Employee^ a, Employee^ b);
    
    		virtual bool Equals(Employee^ other);
    		virtual bool Equals( Object^ obj) override;
    		virtual _int32 GetHashCode() override;
    
    	};
    	}
    }


    FakeCompany.Entities.Employee.cpp file

    // This is the main DLL file.
    
    #include "stdafx.h"
    
    #include "FakeCompany.Entities.Employee.h"
    
    
    bool FakeCompany::Entities::Employee::Equals(Employee^ other)
    {
    	return other != nullptr
    		&& this->Id == other->Id
    		&& this->Age == other->Age
    		&& this->Cuil == other->Cuil
    		&& this->FirstName == other->FirstName
    		&& this->LastName == other->LastName
    		&& this->Email == other->Email;
    }
    
    bool FakeCompany::Entities::Employee::Equals(Object^ obj) 
    {		
    	return obj != nullptr
                && (obj->GetType() == Employee::typeid)
                && this->Equals(dynamic_cast<Employee^>(obj));
    }
    
    _int32 FakeCompany::Entities::Employee::GetHashCode()
    {
    	_int64 hash = 17;	
    
    	hash *= 23 + this->Id.GetHashCode();
    	hash *= 23 + this->Age.GetHashCode();
    	hash *= 23 + this->Cuil == nullptr ? 0 : this->Cuil->GetHashCode();
    	hash *= 23 + this->FirstName == nullptr ? 0 : this->FirstName->GetHashCode();
    	hash *= 23 + this->LastName == nullptr ? 0 : this->LastName->GetHashCode();
    	hash *= 23 + this->Email == nullptr ? 0 : this->Email->GetHashCode();
    
    	return (hash > _int32::MaxValue) ? _int32::MaxValue : hash;
    }
    
    
    bool FakeCompany::Entities::Employee::operator==(Employee^ a, Employee^ b)
    {
    	return Object::ReferenceEquals(a, nullptr)
                    && Object::ReferenceEquals(b, nullptr)
                    || Employee::Equals(a, b);
    }
    
    
    
    bool FakeCompany::Entities::Employee::operator!=(Employee^ a, Employee^ b)
    {
    	return !(a == b);
    }

    Saludos!!!


    • Editado Augusto Pedraza miércoles, 13 de junio de 2012 17:07 Correción código
    • Marcado como respuesta Augusto Pedraza miércoles, 13 de junio de 2012 17:08
    miércoles, 13 de junio de 2012 17:06
  • Augusto, primero que nada, gracias por poner el código final.

    Segundo:  Su implementación de operator==() está haciendo uso del método estático Eployee::Equals(), que no es ninguno de los Equals() que usted escribió.  Entonces pregunto:  ¿De verdad eso funciona?  O tal vez la mejor pregunta sería:  Si usted coloca un punto de interrupción en las implementaciones que usted escribió para Equals(), ¿el depurador se detiene en ellas cuando usted utiliza operator==()?


    Jose R. MCP
    Code Samples

    miércoles, 13 de junio de 2012 19:49
    Moderador
  • Gracias por tu comentario, webJose.

    Estuve chequeando la información del método Object.Equals(Object objA, Object objB) en la MSDN, y este método, funciona de la siguiente manera:

    • Si dos objetos representan la misma referencia, retorna true. Esta comprobación es equivalente a llamar a el método ReferenceEquals (si los dos objetos son null, retorna true)
    • Si cualquiera de los objetos son null, este retorna false.
    • Si los dos objetos no representan la misma referencia y no son null, este llama al método objA.Equals(objB) y retorna el resultado. Esto significa que si objA sobreescribe el método Equals, se invoca a este.

    Saludos!!!

    jueves, 14 de junio de 2012 13:47
  • Ah, pues bien.  Entonces supongo que todo el asunto está en orden.

    Jose R. MCP
    Code Samples

    jueves, 14 de junio de 2012 14:24
    Moderador