boost::bind als friend?



  • Ich rufe boost::bind(..) innerhalb einer methode auf um eine methode der Klasse des Objektes an das aufrufende Objekt zu binden, allerdings bekomme ich folgenden Fehler:

    Connection.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""protected: virtual void __thiscall Connection::do_business(void)" (?do_business@Connection@@MAEXXZ)"
    

    ich vermute es liegt daran das die Methode protected ist, bin mir aber nicht hundert Prozent sicher. Wie kann ich boost::bind(...) zu einem "friend" machen?

    boost::thread _thread(boost::bind(&Klasse::methode,this/*das objekt was die methode zum threaderstellen aufruft und vom Typ Klasse ist*/));
    


  • In wiefern ist denn die Funktion do_business an dem ganzen beteiligt?

    Das sieht nämlich eher danach aus, dass diese Funktion nicht implementiert ist.



  • Jud4s schrieb:

    Wie kann ich boost::bind(...) zu einem "friend" machen?

    Indem du die 77 Überladungen in deine Klasse schreibst. 🕶

    Kleiner Tipp: Tus nicht



  • Ja da lag der Fehler, das waren die Methoden aus der Mutterklasse aus der vererbt wurde, da ich diese virtual gemacht hatte hatte ich sie nicht implementiert.
    Wieso gibt das ein Fehler aus wenn bind expliziet für eine erbende Klassea aufgerufen wird?



  • Jud4s schrieb:

    Das waren die Methoden aus der Mutterklasse aus der vererbt wurde, da ich diese virtual gemacht hatte hatte ich sie nicht implementiert.

    Wenn du die der abgeleiteten Klasse nicht implementiert hast, hast du das gleiche Problem, wie wenn du sie direkt aufrufen würdest: Sie sind zwar deklariert, aber der Linker kann ihre Definition nicht finden.

    Oder redest du von den Basisklassenmethoden? Diese dürften eigentlich rein virtuell sein. Zeig in dem Fall vielleicht ein minimales, komplettes Beispiel, das dein Problem repräsentiert.



  • Jud4s schrieb:

    Wieso gibt das ein Fehler aus wenn bind expliziet für eine erbende Klassea aufgerufen wird?

    Ich versteh die Frage nicht.

    Dass der Fehler von dem gezeigten Code provoziert wird bezweifle ich. Den Fehler hättest du auch so schon bekommen müssen.



  • Basisklasse -vererbt an-> ErbendeKlasse

    in der Mutterklasse habe ich die do_business() methode nur virtuell und nicht implementiert....

    in der ErbendeKlasse ist die do_business() methode implementiert, und auch nur an die wird eigentlich gebunden.

    Aber nachdem ich die virtual methoden aus der Basisklasse auskommentiert hatte klappt es...

    so eine frage am rande... wenn ich thread.timed_join(boost::get_system_time()) aufrufe müsste der thread doch sofort beendet werden oder?



  • Eine nicht implementierte virtuelle Methode ist eigentlich kein Problem ausser du erstellst eine Instanz des Basistypen, dann hat es selbstverständlich keine definierte Methode.
    Oftmals erstellt man sowieso eine abstrakte Basisklasse und dann solltest du ein fälschliche Instanzierung des Basistypen von deinem Compiler mitgeteilt bekommen.



  • drakon schrieb:

    Eine nicht implementierte virtuelle Methode ist eigentlich kein Problem ausser du erstellst eine Instanz des Basistypen, dann hat es selbstverständlich keine definierte Methode.

    Du meinst wahrscheinlich rein virtuelle Methode. Eine virtuelle, nicht implementierte Methode macht dem Linker Probleme (sofern sie aufgerufen wird).

    Jud4s schrieb:

    Aber nachdem ich die virtual methoden aus der Basisklasse auskommentiert hatte klappt es...

    Hier auch; waren die Basisklassenmethoden rein virtuell (mit = 0 )?



  • wenn du das so sagst :), meine Erfahrungen auf dem Gebiet sind noch beschränkt aber ich werde mir es merken, danke.

    Danke nochmals für eure Hilfe

    Hier auch; waren die Basisklassenmethoden rein virtuell (mit = 0)?

    Nein hatte ich nicht, das war der Fehler

    PS: die kleine Frage am rande wär auch noch interressant für mich, da es im laufenden programm nicht klappt. Ich will einen Thread vorzeitig beenden sollte ein bestimmter fall eintreten...

    boost::thread waiting(boost::bind(&methode,this));
    	while(waiting.joinable()) 
    	{
    		if(!running) waiting.timed_join(boost::get_system_time());
    	}
    

    das funktioniert überhaupt nicht... die schleife frisst VIEL zu viele ressourcen... gibt es da eine bessere Lösung?



  • Nexus schrieb:

    drakon schrieb:

    Eine nicht implementierte virtuelle Methode ist eigentlich kein Problem ausser du erstellst eine Instanz des Basistypen, dann hat es selbstverständlich keine definierte Methode.

    Du meinst wahrscheinlich rein virtuelle Methode. Eine virtuelle, nicht implementierte Methode macht dem Linker Probleme (sofern sie aufgerufen wird).

    Nein. Ich habe in der Tat vermutet, dass es kein Problem ist, sofern die Basiklasse nicht instanziert wird, da es ja eine gültige Defintion gibt.
    Ich habs jetzt mal ausprobiert und sie muss nicht einmal aufgerufen werden! Und sie muss auch nicht nicht mal in einer Kindklasse implementiert sein, um einen Fehler vom Linker zu erzeugen.
    Interessant, dass es sich so anders verhält.



  • drakon schrieb:

    Nein. Ich habe in der Tat vermutet, dass es kein Problem ist, sofern die Basiklasse nicht instanziert wird, da es ja eine gültige Defintion gibt.

    Zur Kompilierzeit ist aber oftmals unklar, welche Funktion dynamisch tatsächlich aufgerufen wird, deshalb müssen alle Kandidaten definiert sein.



  • Eine kleine Frage am rande die auch noch interressant für mich wär, da es im laufenden Programm nicht klappt. Ich will einen Thread vorzeitig beenden sollte ein bestimmter Fall eintreten...

    boost::thread waiting(boost::bind(&methode,this)); 
    while(waiting.joinable())  //müsste ja eigtl false zurückliefern wenn der Thread beendet wurde
    { 
    if(!running/*die boolean zur überprüfung ob es beendet werden soll*/) waiting.timed_join(boost::get_system_time()); 
    }
    

    das funktioniert überhaupt nicht... die schleife frisst VIEL zu viele ressourcen... gibt es da eine bessere Lösung? (Kann man mit boost eigtl die Größe des Stacks begrenzen die dem Thread zur verfügung steht wie es mit anderen Thread-typen möglich ist?)

    Und diese methode läuft auch wiederrum in einem thread, also kann running verändert werden 😉 nur so falls einer fagt



  • Jud4s, es übersieht dich schon keiner, du brauchst dich nicht zu wiederholen. 😉

    drakon und ich haben eben nebenbei noch etwas diskutiert, sowas ist hier ziemlich alltäglich. 🙂



  • ok dann srry für doppelposting... dachte nur da meine Frage auf der alten Seite ist nacher newcomer sie nichtmehr sehen



  • Nexus schrieb:

    drakon schrieb:

    Nein. Ich habe in der Tat vermutet, dass es kein Problem ist, sofern die Basiklasse nicht instanziert wird, da es ja eine gültige Defintion gibt.

    Zur Kompilierzeit ist aber oftmals unklar, welche Funktion dynamisch tatsächlich aufgerufen wird, deshalb müssen alle Kandidaten definiert sein.

    Naja. Wenn eine abgeleitete Klasse die Funktion definiert und davon ein Objekt instanziert wird, dann wird aber sicher die Version der abgeleiteten Klasse aufgerufen. Darum habe ich ja gesagt, dass es sicher ein Problem gibt, wenn die Basisklasse instanziert wird und nicht nur ein abgeleiteter Typ.
    Wenn man es polymorph benutzt, dann ist das aber natürlich klar.



  • @Jud: join anstatt joinable. join ist blockierend und kehrt erst dann zurück, wenn der Thread beendet wurde.



  • Ich will das der Thread gezwungen aufhört zu laufen sollte ein bestimmtes ereignis aufgerufen werden.... also quasi ein abbruch. Das Problem ist nur das ich im Thread eine Methode aufrufe die in blocking call ist, deshalb ja den Thread, nach meiner Logik wird die Methode beendeet wenn der Thread beendet wird...nur die Frage ist wie beende ich den thread gesteuert?

    Meine Idee war die while-schleife nur die Zieht 100% CPU leistung



  • drakon schrieb:

    Wenn man es polymorph benutzt, dann ist das aber natürlich klar.

    Ich könnte mir vorstellen, dass ein Compiler virtuelle Aufrufe in offensichtlichen Fällen nicht statisch binden muss, sondern dies als Optimierung durchführen kann (und dann müsste die Basisklassenversion definiert sein).

    Allerdings sehe ich nicht wirklich einen Nutzen von einer (nicht pur) virtuellen Funktion ohne Definition, es handelt sich also mehr um ein theoretisches Problem (das aber durch Linkerfehler sogar auf potentielle Programmfehler hinweisen kann).



  • Nexus schrieb:

    Allerdings sehe ich nicht wirklich einen Nutzen von einer (nicht pur) virtuellen Funktion ohne Definition, es handelt sich also mehr um ein theoretisches Problem (das aber durch Linkerfehler sogar auf potentielle Programmfehler hinweisen kann).

    Das sehe ich auch so. Darum habe ich auch gleich gesagt, dass man eher eine abstrakte Klasse hat als Basis. Ich wär gar nie auf die Idee gekommen so etwas, wie er zu machen. 🤡


Anmelden zum Antworten