2011-01-09 2 views
0
#include <iostream> 
#include <string> 
#include <map> 
#include <vector> 

class base {}; 
class derived1 : public base 
{ 
    public: 
     unsigned short n; 
     derived1() 
     { 
      n = 2; 
     } 
}; 
class derived2 : public base {}; 

void main() 
{ 
    // way 1 
    { 
     std::vector<derived1> a1; 
     std::vector<derived2> a2; 
     std::map<std::string, base*> b; 
     a1.push_back(derived1()); 
     b["abc"] = &a1.at(0); 
     std::cout<<(dynamic_cast<derived1*>(b.find("abc")->second))->n<<std::endl; 
    } 

    // way 2 
    { 
     std::map<std::string, base*> b; 
     b["abc"] = new derived1(); 
     std::cout<<dynamic_cast<derived1*>(b.find("abc")->second)->n<<std::endl; 
     delete dynamic_cast<derived1*>(b.find("abc")->second); 
    } 
} 

Der Fehler ist "'dynamic_cast': 'Basis' ist kein polymorpher Typ". Was sollte getan werden, um dies zu beheben? Ist alles richtig in beiden Weg 1 und Weg 2 bereinigt?warum die polymorphen Typen Fehler und Bereinigung Frage?

+2

'main' Rückgabetyp sollte nicht' void' sein. – Mahesh

Antwort

7

Um Base einen polymorphen Typ zu machen, müssen Sie ihm mindestens eine virtuelle Funktion geben. Die einfachste in diesem Fall wäre der destructor:

class Base { 
public: 
    virtual ~Base() { } 
}; 

In Bezug auf Ihre Frage zu Bereinigungs:
Technisch gibt es einige nicht definiertes Verhalten in beiden Richtungen, da die Objekte, die die Karte zerstört bezieht vor Die Zeiger werden aus der Karte entfernt. Dies hat zur Folge, dass die Karte, wenn sie zerstört wird, ungültige Zeiger enthält, was zu undefiniertem Verhalten führt.
Aus praktischen Gründen verursacht dies keine Probleme mit einem bekannten Compiler.

Ansonsten sind Sie richtig sauber alles.
Aber in Weg2 können Sie eine Vereinfachung vornehmen. Wenn Base einen virtuellen Destruktor hat, können Sie einfach ohne die dynamische Umwandlung

delete b.find("abc")->second; 

tun.

+0

Danke für die gut geschriebene Antwort. Ich bin überrascht und sehr erfreut, dass ich die Löschzeile in way2 vereinfachen kann. So kann ich Objekte auf der anderen Seite von Zeigern aufräumen, wo ich nicht alle Informationen über den Typ des Objekts weiß, auf das gezeigt wird. – alan2here

+0

Dangling-Zeiger verursachen kein undefiniertes Verhalten, wenn sie nicht dereferenziert werden. Und eine 'map ' deserenziert keinen ihrer 'base *' Zeiger in ihrem Destruktor oder irgendeiner anderen Methode. – aschepler

+0

@ascheppler: Dangling-Zeiger verursachen UB (obwohl mit typischen positiven Effekten), wenn sie in einem Kontext verwendet werden, in dem eine "Lvalue-to-rvalue-Konvertierung" auftritt. Eine solche Umwandlung tritt auf, wenn eine Map ihren Inhalt zerstört. –