# Qt: Eigene Klasse: undefined reference



## Termy2007 (16. September 2008)

Hi..

Ich habe (wie so oft^^) ein kleines Problem  in C++.. 
Ich habe heute ein Buch bekommen über die Programmierung mit Qt.. und hab mich auch gleich ranngehockt damit was zu machen!

Was ich nun vorhabe ist eine Klasse mit eigenen Slots und Signalen zu erstellen.
Diese sieht bisher so aus:


```
class Encrypt : public QObject
{
    Q_OBJECT

//private:
public:
Encrypt();

public slots:
    void doEncrypt(string, string, QTextEdit*);

signals:
    void finished();


};
```

Die Includes habe ich natürlich nicht vergessen 

Hier der Rest zu der Klasse (.cpp):

```
void Encrypt::doEncrypt(string pw, string emailtext, QTextEdit *pwfeld)
    {
        string crypted = pacP(pw);
        pwfeld->setText(crypted.c_str());
        emit finished();
    }
```

Wenn ich das jetzt kompilieren will wirft er mir folgende Fehler aus:
- undefined reference to`Encrypt::finished()'
- undefined reference to `Encrypt::Encrypt()'

Wenn ich die beiden Funktionen dann allerdings definiere (was ich eigentlich nicht machen müsste (dem Buch zufolge)).. dann wirft er mir einen Fehler wegen undefinierten vtables aus... 

Weiß jemand Rat?
Termy


----------



## Online-Skater (16. September 2008)

Hallo,

bei mir funktioniert das Beispiel habe nur den Defaul Konstruktor um 2 Klammern erweitert so das er nichts tut. Getestet mit CodeBlocks (MinGW)


```
#ifndef ENCRYPT_H
#define ENCRYPT_H

#include <QObject>
#include <QTextEdit>

class Encrypt : public QObject
{
    Q_OBJECT

//private:
public:
    Encrypt() {};

public slots:
    void doEncrypt(std::string, std::string, QTextEdit*);

signals:
    void finished();

};

#endif
```


```
#include <QApplication>
#include "Encrypt.h"

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    Encrypt test;

    return app.exec();
}
```

Nicht vergessen ein Projektfile generieren/erstellen zu lassen aus dem die MakeFiles generiert werden, welche man zum kompilieren benutzt. Falls du nicht weißt was das bedeutet dann im "*Assistant*" nachlesen.

mfg


----------



## Termy2007 (16. September 2008)

Danke für deine Hilfe.
Wenn ich das genau so mache wie du es beschrieben hast passiert genau das was ich erwartet habe:
2 Errors:
- undefined reference to `Encrypt::finished()'  ->> Genau bei der "emit" Stelle!
- \..\..\src\corelib\tools\qstring.h||undefined reference to `vtable for Encrypt'

Naja.. ich habe jetzt sowieso rausgefunden dass auch der Rest meines Codes praktisch sinnlos ist.. er funktioniert zwar technisch.. würde aber nicht das bewirken was er sollte^^

Das kommt davon wenn man außerhalb des Buches experimentiert..
ich werde das ganze jetzt nochmal nach dem Buch machen.. und dann mal sehen obs funktioniert.. wenn nicht melde ich mich natürlich wieder ;-)

Ach ja.. noch eine Frage die mir das Buch nicht beantworten konnte:
Wozu diese Präprozessordirektiven (ich habe sie.. keine Sorge^^):

```
#ifndef ENCRYPT_H
#define ENCRYPT_H
.
.
.
#endif
```


----------



## devDevil (16. September 2008)

Nja kenn mich mit den ganzen Makros usw. von Qt nicht aus. Aber prinzipiell ist es so: Wird eine Funktion nicht genutzt, brauchst du sie nicht zu definieren, eine deklaration reicht.


----------



## Online-Skater (16. September 2008)

devDevil hat gesagt.:


> Nja kenn mich mit den ganzen Makros usw. von Qt nicht aus. Aber prinzipiell ist es so: Wird eine Funktion nicht genutzt, brauchst du sie nicht zu definieren, eine deklaration reicht.



Richtig und genau deshalb sollte sein Code funktionieren sowie meiner es tut. Daher liegt es an etwas anderem z.B. Compiler Einstellung bzw. makefiles usw.



Termy2007 hat gesagt.:


> Ach ja.. noch eine Frage die mir das Buch nicht beantworten konnte:
> Wozu diese Präprozessordirektiven (ich habe sie.. keine Sorge):



Ich habs nicht aus offiziellen Quellen daher ist dies nur Halbwissen bzw. eigene Herleitungen:
Dieses Konstrukt dient zur Verhinderung von Mehrfach-Inkludierungen, sobald eine Datei diesen Header inkludiert ist die Konstante *ENCRYPT_H* noch nicht definiert daher gibt die Anweisung _if not defined ENCRYPT_H_ 1 bzw. true und sie wird dann definiert sowie die Klasse eingebunden. Wird sie nochmals irgendwo anders eingebunden liefert _ifndef_ eine 0, die Bedingung ist nicht erfüllt da ENCRYPT_H bereits existiert und somit sollte das nachfolgende auch nicht "beachtet" werden. Der Päprozessor setzt vor dem eigentlichen Kompilieren ein.

Wenn was falsch sein sollte berichtigt ihr mich schon 
Viel Erfolg noch mit Qt ist echt nen tolles Framework, besonders die Dokumentation löst sogut wie alle Probleme also programmiertechnischer Herkunft ;-)

mfg


----------



## devDevil (16. September 2008)

Nja der gezeigte Code spricht ja nicht für Qt, aber okay 

Es handelt sich dabei um ein ganz spezielles Konstrukt (bei den Präprozeessoranweisungen), nämlich um den sog. "Include-Guard", der die Mehrfacheinbindung verhindert. Damit will ich dein Halbwissen mal bestätigen. Alternativ kannst du auch #pragma once nutzen, was unter bestimmten vorraussetzungen sogar Vorteile aufweißt, zeitweise aber nicht von allen Compilern unterstützt wurde.


----------



## Termy2007 (17. September 2008)

Danke für die zahlreichen und aufschlussreichen Antworten ;-)

Inzwischen konnte ich das Problem lösen: 
Es lag daran dass ich vergessen habe qmake als Standart einzurichten und er damit nicht das Makro (Q_OBJECT) meiner Klasse übersetzt hat und somit die ungewöhnlichen Fehler ausgeworfen hat.

Das Programm funktioniert nun einwandfrei 

Was benutzt ihr eigentlich an IDE's wenn ihr mit Qt programmiert?
Weil mit Code::Blocks habe ich es nicht zum Laufen gebracht.. benutze jetzt QDevelop..


----------



## Online-Skater (17. September 2008)

Habe bisher immer Code::Blocks benutzt und bin eigentlich auch recht zufrieden damit nur wenn man mal im Genuss des Debuggers von der MS Visual 2008 Reihe gekommen ist dann kann man schon mal fremdgehen 

Achso bei CodeBlocks must du halt nur darauf achten du das Häckchen bei "This is a custom makefile" rausnimmst so nimmt er die Makefiles die im Ordner liegen (by qmake).

Ich werde mal QDevelop ausprobieren habe noch nichts darüber gehört 

mfg


----------

