Ist es möglich, Klassendeklaration und Implementierung in derselben .cpp-Datei zu haben?
Ich möchte einige Unittests mit Hilfe eines Mock-Objekts machen. Hier ist ein Beispiel meines Tests:
// Einige Include-Anweisungen entfernt
#include "abstractconnection.h"
class ConnectionMockup : public AbstractConnection
{
Q_OBJECT
public:
explicit ConnectionMockup(QObject *parent = 0);
bool isReady() const;
void sendMessage(const QString &message);
void test_send_message(const QString &message);
bool ready;
QStringList messages;
};
ConnectionMockup::ConnectionMockup(QObject *parent)
: AbstractConnection(parent)
{
ready = true;
}
bool ConnectionMockup::isReady() const
{
return ready;
}
void ConnectionMockup::sendMessage(const QString &message)
{
messages.append(message);
}
void ConnectionMockup::test_send_message(const QString &message)
{
emit messageRecieved(message);
}
TestEmcProgram::TestEmcProgram(QObject *parent) :
QObject(parent)
{
}
void TestEmcProgram::open()
{
ConnectionMockup mockup;
EmcProgram program(&mockup);
QCOMPARE(...
...
...
Wie Sie sehen können, wird die Klasse ConnectionMockup nur von der Klasse TestConnection verwendet, und ich brauche sie nirgendwo anders. Also, wenn ich versuche, dieses Programm zu kompilieren, erhalte ich folgenden Fehler:
> testemcprogram.o: In Funktion
> `ConnectionMockup':
> /home/sasa/Desktop/QtPro/FocoKernel-build-desktop/../FocoKernel/testemcprogram.cpp:29:
> undefinierter Verweis auf `Virtuelle Tabelle für
> ConnectionMockup'
> /home/sasa/Desktop/QtPro/FocoKernel-build-desktop/../FocoKernel/testemcprogram.cpp:29:
> undefinierter Verweis auf `Virtuelle Tabelle für
> ConnectionMockup' testemcprogram.o: In
> Funktion `~ConnectionMockup':
> /home/sasa/Desktop/QtPro/FocoKernel-build-desktop/../FocoKernel/testemcprogram.cpp:14:
> undefinierter Verweis auf `Virtuelle Tabelle für
> ConnectionMockup'
Ist es möglich, die Deklaration hier zu lassen, oder muss ich eine Header-Datei erstellen und die Deklaration in diese Datei verschieben?
EDIT: Da Herr Jerry Coffin (Danke, Herr Coffin) vorgeschlagen hat, dass möglicherweise einige virtuelle Funktionen nicht implementiert sind, werde ich hier die Deklaration von AbstractConnection einfügen, damit wir diese Möglichkeit überprüfen können:
#include
class AbstractConnection : public QObject
{
Q_OBJECT
public:
explicit AbstractConnection(QObject *parent = 0);
virtual ~AbstractConnection();
virtual bool isReady() const = 0;
signals:
void messageRecieved(const QString &message);
public slots:
virtual void sendMessage(const QString &message) = 0;
};
LÖSUNG: Dank @JCooper, @iammilind und @Jerry Coffin haben wir die Lösung. Nachdem der Destruktor aus AbstractConnection entfernt wurde (da er tatsächlich nichts tut) und Q_OBJECT aus ConnectionMockup entfernt wurde, funktioniert es.
0 Stimmen
Danke. Ich habe es im Text jetzt korrigiert.
0 Stimmen
@Sasa: Ich habe den ersten Satz bewusst nicht korrigiert.. Deklaration und Implementierung sind hier synonym. ;)
0 Stimmen
@0A0D: Tatsächlich ist es nicht. Eine Klassendeklaration sieht so aus:
class myclass;
Etwas wie:class myclass { /* ... */ };
ist eine Klassendefinition. Sie können dann Klassenmember separat von der Definition der Klasse selbst definieren.0 Stimmen
@Xeo: Keine Korrektur ist erforderlich - die Terminologie, die Sie haben, ist bereits korrekt.
0 Stimmen
Nun ja, ich habe mich gerade in diesen Begriffen verloren :). Ich dachte, dass: Deklaration ist, wenn Sie eine Header-Datei einbeziehen oder eine Vorwärtsdeklaration verwenden. Definition ist das, was Sie in der Header-Datei eingeben, und Implementierung ist das, was Sie in der Quelldatei eingeben. Aber ich weiß nicht mehr, was richtig ist. :)
1 Stimmen
Ich habe wieder durcheinander gebracht, mein Fehler. Diese Antwort von @sbi ist wirklich hilfreich, um zwischen Definition und Deklaration zu unterscheiden. :)