2017-06-22 2 views
-3

Ich habe viele Antworten gesucht, aber keiner von ihnen kann mein Problem lösen, ich bin neu in C++, dieses Problem ist ziemlich mit mir verdrahtet. Unten ist eine vereinfachte Extraktion meines Codes.C++ undefined Verweis auf Vtable Ausnahme

TestHeader.h:

#ifndef NAMESPACE_TESTHEADER_H_ 
#define NAMESPACE_TESTHEADER__H_ 

namespace Namespace { 

class TestHeader { 

    public: 

    TestHeader(const std::string& str) : anyString_(str) { } 

    virtual std::string methodOne(const std::string& param) const; 

    virtual ~TestHeader() { anyString_.clear(); } 

    protected: 
     std::string anyString_; 
}; 
} 

#endif //NAMESPACE_TESTHEADER__H_ 

TestHeader.cpp:

#include "TestHeader.h" 

using namespace std; 

namespace Namespace { 

TestHeader::TestHeader(const std::string& str):anyString_(str) { <do something>; } 

std::string TestHeader::methodOne(const std::string& param) const 
{ 
    return <A string>; 
} 

TestHeader::~TestHeader() { 
    anyString_.clear(); 
} 
} 

Was habe ich einfach diese Zeile in einem anderen CPP in meinem Paket rufen wurde:

#include "TestHeader.h" 
TestHeader testHeader("whatever"); 

Der Build ist fehlgeschlagen, indem

geworfen wurde

Das Seltsame ist: wenn ich virtual std::string methodOne(const std::string& str) const; in Header und dessenderen Umsetzung in CPP-Kommentar aus, OR, wenn ich : anyString_(str) nach Konstruktor kommentieren und anyString_.clear(); in destructor zusammen nur in Header, wird die Build erfolgreich zu sein.

+1

verwendet wird, verweigert. Warum haben Sie den Konstruktor und Destruktor zweimal definiert? Es sollte nicht kompiliert werden, was mich denken lässt, dass Sie Ihre Quellen nicht korrekt kompiliert und verlinkt haben. – Curious

+0

Ich denke, es wird keine Neudefinition von Konstruktor und Destruktor kompilieren. – user1438832

+2

Sie enthalten 'std :: string' nicht in Ihrer Kopfzeile. Es gibt keine Möglichkeit, dass der Fehler nur bei der Verknüpfung auftritt. Veröffentlichen Sie eine richtige [mcve], keine verdummte Version, die nichts reproduziert. – StoryTeller

Antwort

0

Erstens, #include <string> an der Spitze Ihrer Header-Datei. Ich vermute, der Fehler ist, weil Sie nicht die Objektdatei nach der Herstellung verknüpft haben TestHeader.cpp mit der Quelldatei kompilieren, die die Deklaration und Initialisierung für die Variable testHeader

diese Stellen mit dem folgenden Befehl namens enthält und Sie sollten einen Linker-Fehler sehen dass beschwert sagen, dass Sie mehrere Definitionen für den Konstruktor haben

g++ -std=c++14 TestHeader.cpp yourfile.cpp 

Nachdem Sie diese Fehler sehen, entfernen Sie die mehrere Definitionen, entweder setzen alle Definitionen in der CPP-Datei oder sie nur an einer Stelle setzen und dann neu kompilieren und Link mit dem obigen Befehl. Der Linker-Fehler sollte weg sein.

1

Zuerst sollten Sie den Konstruktor und den Destruktor nicht zweimal definieren. Es sollte nicht kompiliert werden, wie von Curious in Kommentaren erwähnt

Zweitens gehe ich davon aus, dass Sie die Klasse nicht abstrakt sein wollen, da kein Runtime-Polymorphismus implementiert ist, was die grundlegende Verwendung von virtuellen Funktionen ist.

Wenn Sie nicht die Klasse wollen TestHeader abstrakt entfernen sein das virtual Schlüsselwort, das zu Virtual Table .C bezieht ++ Compiler fügt virtuelle Tabelle für jede Klasse virtuelle Funktion oder Klasse aus der Klasse geerbt hat, die virtuellen Funktionen hat.

Besser studieren Sie die Verwendung von Virtual Schlüsselwort und dann schreiben Sie den Code. Hier sind schnelle Verbindungen für den gleichen Link 1 Link 2

Auch ich glaube, Sie virtual ~TestHeader() { anyString_.clear(); } einige Konzepte von Destructor denken müssen keinen Sinn machen. Tatsächlich gibt es keine Basisklasse, die wiederum die Verwendung von Virtual Destructor, die im Fall von Inheritance