[gelöst]QList::contains() mit benutzerdefinierten Datentypen

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
Bronski
Beiträge: 44
Registriert: 10. Oktober 2008 13:46

[gelöst]QList::contains() mit benutzerdefinierten Datentypen

Beitrag von Bronski »

Hallo,
Was muß ich im einzelnen tun um in einer Liste von Benutzer definierten Datentypen, Methoden wie QList::contains( const T & value ) ,QList::count( const T & value ) etc. verwenden zu können ?

Ich habe eine eigene Klasse erstellt (Tmessage)
BaseServer.h

Code: Alles auswählen

class Tmessage:public QByteArray
{

private:
protected:

public:
Tmessage();
~Tmessage();


bool valid;
QList<Terror_msg> errors;

virtual Tmessage_hdr get_message_hdr();
virtual bool         set_message_hdr(Tmessage_hdr);
virtual bool         change_message_hdr(Tmessage_hdr);

bool operator==(/*const */Tmessage );
bool operator==(Tmessage_hdr );
bool operator==(const Tmessage &) const;
bool operator==(/*const */Tmessage_hdr );

bool operator!=(/*const*/ Tmessage );
bool operator!=(Tmessage_hdr );
bool operator!=(const Tmessage & ) const;
bool operator!=(/*const */Tmessage_hdr );

};
Q_DECLARE_METATYPE(Tmessage);

BaseServer.cpp

Code: Alles auswählen

/***********************************************************************
 -----------------------------------------------------------------------
 -                        Tmessage methods                             -
 -----------------------------------------------------------------------
 ***********************************************************************/
Tmessage::Tmessage()
{
valid = true;
}

Tmessage::~Tmessage()
{
}

Tmessage_hdr Tmessage::get_message_hdr()
{

if(this->size()<sizeof(Tmessage_hdr))
{
//critical error
}


Tmessage_hdr message_hdr;

QVariant converter(this->left(sizeof(Tmessage_hdr)));

  if (converter.canConvert<Tmessage_hdr>())
  {
  message_hdr = converter.value<Tmessage_hdr>();
  }
  else
  {
   //critical error
  }
return message_hdr;
}

bool Tmessage::set_message_hdr(Tmessage_hdr message_hdr)
{
QByteArray message_hdr_array;
QVariant converter;
converter.setValue(message_hdr);

   if (converter.canConvert<QByteArray>())
   {
   message_hdr_array = converter.value<QByteArray>();
   this->prepend(message_hdr_array);
   return true;
   }
   else
   {
   return false;
   }
}

bool Tmessage::change_message_hdr(Tmessage_hdr message_hdr)
{
QByteArray message_hdr_array;
QVariant converter;
converter.setValue(message_hdr);

   if (converter.canConvert<QByteArray>())
   {
   message_hdr_array = converter.value<QByteArray>();
   this->replace(0,sizeof(Tmessage_hdr),message_hdr_array);
   return true;
   }
   else
   {
   return false;
   }
}

bool Tmessage::operator==(/*const*/ Tmessage &other) //const 
{
const Tmessage_hdr message_hdr = (const Tmessage_hdr) this->get_message_hdr();
//message_hdr = this->get_message_hdr();

const Tmessage_hdr other_message_hdr = (const Tmessage_hdr) other.get_message_hdr();
//other_message_hdr = other.get_message_hdr();


  if(message_hdr.id_nr == other_message_hdr.id_nr)
  {
  return true;
  }
  
  
return false;
}


bool Tmessage::operator!=(/*const*/ Tmessage &other) //const 
{
const Tmessage_hdr message_hdr = (const Tmessage_hdr) this->get_message_hdr();
//message_hdr = this->get_message_hdr();

const Tmessage_hdr other_message_hdr = (const Tmessage_hdr) other.get_message_hdr();
//other_message_hdr = other.get_message_hdr();


  if(message_hdr.id_nr != other_message_hdr.id_nr)
  {
  return true;
  }
  
  
return false;
}

bool Tmessage::operator==( Tmessage_hdr other) 
{
Tmessage_hdr message_hdr =   this->get_message_hdr();
//message_hdr = this->get_message_hdr();

// Tmessage_hdr other_message_hdr =  other.get_message_hdr();
//other_message_hdr = other.get_message_hdr();


  if(message_hdr.id_nr == other.id_nr)
  {
  return true;
  }
  
  
return false;
}

bool Tmessage::operator!=(Tmessage_hdr other)  
{
Tmessage_hdr message_hdr =   this->get_message_hdr();
//message_hdr = this->get_message_hdr();

// Tmessage_hdr other_message_hdr =  other.get_message_hdr();
//other_message_hdr = other.get_message_hdr();


  if(message_hdr.id_nr != other.id_nr)
  {
  return true;
  }
  
  
return false;
}


bool Tmessage::operator==(const Tmessage_hdr &other) const 
{
const Tmessage_hdr message_hdr =   this->get_message_hdr();
//message_hdr = this->get_message_hdr();

// Tmessage_hdr other_message_hdr =  other.get_message_hdr();
//other_message_hdr = other.get_message_hdr();


  if(message_hdr.id_nr == other.id_nr)
  {
  return true;
  }
  
  
return false;
}

bool Tmessage::operator!=(const Tmessage_hdr &other) const 
{
const Tmessage_hdr message_hdr =   this->get_message_hdr();
//message_hdr = this->get_message_hdr();

// Tmessage_hdr other_message_hdr =  other.get_message_hdr();
//other_message_hdr = other.get_message_hdr();


  if(message_hdr.id_nr != other.id_nr)
  {
  return true;
  }
  
  
return false;
}

Anscheinend kann man den die Funktionen:
bool Tmessage::operator==( Tmessage_hdr other)
bool Tmessage::operator!=(Tmessage_hdr other)
nicht überladen


Ich erhalte die Fehlermeldung:

Code: Alles auswählen

src/BaseServer.h:183: error: ‘bool Tmessage::operator==(Tmessage_hdr)’ cannot be overloaded
src/BaseServer.h:181: error: with ‘bool Tmessage::operator==(Tmessage_hdr)’
src/BaseServer.h:188: error: ‘bool Tmessage::operator!=(Tmessage_hdr)’ cannot be overloaded
src/BaseServer.h:186: error: with ‘bool Tmessage::operator!=(Tmessage_hdr)’


Wenn ich die Methoden weglasse, oder es mit bool Tmessage::operator==(const Tmessage_hdr)const oder ähnlichem versuche erhalte ich an der Stelle, wo ich die Liste mit QList::contains(messages) verwende, folgende Fehlermeldung:

Code: Alles auswählen

/*adds ammessage to the message list.
The function has to be converted for working without index list
as soon as Tmessages "==" oprators work */
void  Tconnection_manager::add_message(Tmessage message)
{
const Tmessage_hdr message_hdr = message.get_message_hdr();
//message_hdr = message.get_message_hdr();


  if(messages.contains(message_hdr))
  {
  //error: message is already existing
  }

messages.append(message);
//index.append(message_hdr.id_nr);
}

Code: Alles auswählen

src/BaseServer.cpp: In member function ‘virtual void Tconnection_manager::add_message(Tmessage)’:
src/BaseServer.cpp:1563: error: no matching function for call to ‘QList<Tmessage>::contains(const Tmessage_hdr&)’
/usr/include/QtCore/qlist.h:654: note: candidates are: QBool QList<T>::contains(const T&) const [with T = Tmessage]
Zum Schluss werden die Datentypen mit folgender Funktion registriert:

Code: Alles auswählen


/*************************************************************
 *                      Functions                            *
**************************************************************/

void register_base_server_metatypes()
{
qRegisterMetaType<Tmessage_hdr>("Tmessage_hdr");
qRegisterMetaType<Tmessage>("Tmessage");
qRegisterMetaType<Tconnection_state_name>("Tconnection_state_name");
qRegisterMetaType<Treply>("Treply");
qRegisterMetaType<Treply>("Tcm_command");
qRegisterMetaType<Tconnect_address_para>("Tconnect_address_para");
qRegisterMetaType<Tconnect_string_para>("Tconnect_string_para");
qRegisterMetaType<Tconnection_info>("Tconnection_info");

qRegisterMetaType<Tmessage_hdr_con_para>("Tmessage_hdr_con_para");

qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState");
qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
}
Was mache ich falsch ?
Zuletzt geändert von Bronski am 24. November 2009 12:47, insgesamt 1-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Hast Du jetzt bool operator==(const Tmessage &) const; implementiert oder nicht? Komme nicht ganz raus was du mit 'weglassen' meinst. bool operator==(const Tmessage &) const; muss schon da sein...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Code: Alles auswählen

rc/BaseServer.cpp:1563: error: no matching function for call to ‘QList<Tmessage>::contains(const Tmessage_hdr&)’ 
Warum sollte

Code: Alles auswählen

  if (kartoffelsack.enthaelt(ruebe42))
funktionieren? Warum suchst du in einer Liste von "Tmessages" nach einem "Tmessage_hdr"?

Code: Alles auswählen

if(messages.contains(message)) 
klingt irgendwie sinnvoller.. oder?
Bronski
Beiträge: 44
Registriert: 10. Oktober 2008 13:46

Beitrag von Bronski »

Ich scheine das Problem gelöst zu haben.

Ich habe die letzten Tage,versucht Operatoren zu überladen und mich dabei an Code-Beispielen bedient ohne sie hundertprozentig zu verstehen.
Was eine Referenz ist, wusste ich zwar,- aber da ich das in früheren Programmiersprachen wie C und Delphi nie gebraucht habe,viel es mir als C++ Anfänger schwer dieses als solches zu erkennen bzw. damit zu arbeiten.

Ich habe jedenfalls die Anzahl der überladenen Operatoren auf 4 begrenzt:

Code: Alles auswählen

class Tmessage:public QByteArray
{

private:
protected:

public:
Tmessage();
~Tmessage();


bool valid;
QList<Terror_msg> errors;

virtual Tmessage_hdr get_message_hdr() const;
virtual bool         set_message_hdr(Tmessage_hdr);
virtual bool         change_message_hdr(Tmessage_hdr);

bool operator==(const Tmessage &) const;
bool operator!=(const Tmessage & ) const;
bool operator==(const Tmessage_hdr &) const;
bool operator!=(const Tmessage_hdr & ) const;


};
Q_DECLARE_METATYPE(Tmessage);

Tmessage::Tmessage()
{
valid = true;
}

Tmessage::~Tmessage()
{
}

Tmessage_hdr Tmessage::get_message_hdr()const
{

if(this->size()<sizeof(Tmessage_hdr))
{
//critical error
}


Tmessage_hdr message_hdr;

QVariant converter(this->left(sizeof(Tmessage_hdr)));

  if (converter.canConvert<Tmessage_hdr>())
  {
  message_hdr = converter.value<Tmessage_hdr>();
  }
  else
  {
   //critical error
  }
return message_hdr;
}

bool Tmessage::set_message_hdr(Tmessage_hdr message_hdr)
{
QByteArray message_hdr_array;
QVariant converter;
converter.setValue(message_hdr);

   if (converter.canConvert<QByteArray>())
   {
   message_hdr_array = converter.value<QByteArray>();
   this->prepend(message_hdr_array);
   return true;
   }
   else
   {
   return false;
   }
}

bool Tmessage::change_message_hdr(Tmessage_hdr message_hdr)
{
QByteArray message_hdr_array;
QVariant converter;
converter.setValue(message_hdr);

   if (converter.canConvert<QByteArray>())
   {
   message_hdr_array = converter.value<QByteArray>();
   this->replace(0,sizeof(Tmessage_hdr),message_hdr_array);
   return true;
   }
   else
   {
   return false;
   }
}

bool Tmessage::operator==(const Tmessage &other) const 
{
 Tmessage_hdr message_hdr =   this->get_message_hdr();
//message_hdr = this->get_message_hdr();

 Tmessage_hdr other_message_hdr ;
 other_message_hdr = other.get_message_hdr();


  if(message_hdr.id_nr == other_message_hdr.id_nr)
  {
  return true;
  }
  
  
return false;
}

bool Tmessage::operator!=(const Tmessage &other) const 
{
 Tmessage_hdr message_hdr =   this->get_message_hdr();
//message_hdr = this->get_message_hdr();

Tmessage_hdr other_message_hdr ;
other_message_hdr = other.get_message_hdr();


  if(message_hdr.id_nr != other_message_hdr.id_nr)
  {
  return true;
  }
  
  
return false;
}


bool Tmessage::operator==(const Tmessage_hdr &other_message_hdr) const 
{
 Tmessage_hdr message_hdr =   this->get_message_hdr();
//message_hdr = this->get_message_hdr();



  if(message_hdr.id_nr == other_message_hdr.id_nr)
  {
  return true;
  }
  
  
return false;
}

bool Tmessage::operator!=(const Tmessage_hdr &other_message_hdr) const 
{
 Tmessage_hdr message_hdr =   this->get_message_hdr();
//message_hdr = this->get_message_hdr();



  if(message_hdr.id_nr != other_message_hdr.id_nr)
  {
  return true;
  }
  
  
return false;
}

Die zweite tükische Sache war, das die Funktion get_message_hdr() als const deklariert sein muss, da sie aus einer als const deklarierten Funktion aufgerufen wurde.
(Ich hoffe, ich habe dies so richtig wiedergegeben)

Gerade die Verwendung von const scheint für Anfänger, wie mich ,voll von Fallstricken zu sein.
Wem es ähnlich dabei geht, folgendes Tutorial war sehr hilfreich:

http://www.possibility.com/Cpp/const.html


Eure Hinweise waren jedenfalls sehr hilfreich und ich danke euch sehr für eure Bemühungen. :D
Antworten