2012-04-10 10 views
0

Ich habe eine leicht modifizierte Version der Thread-Klasse kopiert aus dem Linux Self Help Website, die ich verwendet habe, eine Threading-Basisklasse zu erstellen:Warum wurde das überladene Element nicht vom Thread aufgerufen?

class Thread 
{ 
public: 
static void *entry (void *pvArg) { Thread *pobjThread = static_cast<Thread *> (pvArg); pobjThread->run(); } 
virtual void run (void) = 0; 
}; 

Ich habe 2 Thread Klassen:

class Item : public Thread 

und

class Item startet den Thread aus dem Konstruktor der Funktion, die Klasse in Pthread Bibliothek zum Erstellen der Thread-Aufruf entry mit this als pvArg während class Product erstellt Thread später während der Programmausführung.

Jetzt ist die Sache, class Item funktioniert gut. Die run Funktion wird aufgerufen und ordnungsgemäß verarbeitet. Wenn jedoch class Product später die gleiche Funktion aufruft, die ich erhalte:

pure virtual method called 

Beiden Klassen haben die gleiche Umsetzung mit der run Methode Überlastung, aber man wird aufgerufen und der andere nicht.

Warum würde ich plötzlich eine pure virtual method called Ausnahme bekommen?

Danke.

Update: class Item anders ist die class Product weil Item als static Item item; in der CPP-Datei deklariert wird, und es gibt nur einen. class Product wird wie ein normales Objekt verwendet. Wenn ich die gleiche Sache mit class Product mache, funktioniert es gut.

+0

Sind Sie sicher, dass 'Product' nicht von' Item' abgeleitet ist? Das würde den Fehler erklären. – modelnine

+0

@PlasmaHH - Die Ausnahme kommt von der normal aufgerufenen Klasse. Der Aufruf vom ctor (von 'Item') funktioniert korrekt. – user626201

+0

@modelnine - nein, sie sind deutlich unterschiedliche Klassen. Es gibt keine Verbindung, auch nicht in Header-Includes (außer dem Thread-Header). – user626201

Antwort

0

Dank was modelnine darauf hingewiesen hat, haben wir festgestellt, dass der fehlerhafte Code ein Objekt erstellt, den Thread gestartet und das Objekt dann zerstört hat, bevor der Thread eine Chance hatte zu laufen. Dies, wie modelnine angezeigt, lösche die vtable, und das verursachte das Problem.

Dank modelnine in den Kommentaren der Frage.

1

Rufen Sie keine virtuellen Funktionen von einem Konstruktor oder einem Destruktor auf - die Vererbungskette ist unvollständig, wenn Code in beiden ausgeführt wird, und daher gibt es keine sinnvolle Möglichkeit, virtuelle Funktionen aufzurufen. Eine andere Antwort finden Sie unter Pure virtual invocation from constructor and destructor.

0

Artikel und Produkt sind: public Thread bedeutet, dass Sie eine virtuelle Funktion (von sich selbst) im Konstruktor aufrufen würden. Innerhalb des Konstruktors ist die vtable noch nicht vollständig eingerichtet (da sie von jeder Basisklasse abhängt, die initialisiert wird), so dass Sie ein undefiniertes Verhalten erhalten.

Best Practice: nicht virtuelle Funktionen aus einem Konstruktor/Destruktor aufrufen. Halten Sie Konstruktoren/Destruktoren sehr einfach, machen Sie den Rest der Arbeit in einer init() - Funktion oder so.

+0

@phresnel: Es ist nur verboten, eine * pure * virtuelle Funktion aufzurufen; Das Aufrufen einer nicht-reinen Funktion von einem Konstruktor ist gut definiert und könnte gelegentlich eine vernünftige Sache sein. –

+0

@MikeSeymour: Irgendwie lese ich eigentlich "pure", aber ich denke, mein Unterbewusstsein jongliert Wörter zu viel beim Lesen. –

Verwandte Themen