Klassenproblem

sunmania

Mitglied
Irgendwie habe ich Tomaten auf den Augen, denn ich sehe irgendwie nicht wo der Fehler liegt.

Also, ich habe eine Klasse erstellt, die sidc heisst, in der einige Fkt. deklariert sind...

Ein Bsp. aus meiner sidc.cpp
C/C++ Code:
Code:
void sidc::success() {
    gtk_init(NULL,NULL);
    dtable    = gtk_table_new(2, 1, FALSE);
    dbox  = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(dbox), "Meldung");
    dtext = gtk_label_new("Der Schueler konnte erfolgreich hinzugefuegt werden");
    gtk_table_attach(GTK_TABLE(dtable), dtext, 0, 1, 0, 1, GTK_FILL , GTK_FILL, 2, 2);
    dok = gtk_button_new_with_label("OK");
    gtk_table_attach(GTK_TABLE(dtable), dok, 0, 1, 1, 2, GTK_EXPAND, GTK_FILL, 2, 2);
    gtk_signal_connect(GTK_OBJECT(dok), "clicked",GTK_SIGNAL_FUNC(&sidc::destroydbox), NULL); /*  Hier soll der Fehler sein,
aber wenn ich nur &destroydbox schreibe,
sagt er mir auch Fehler und will das ich &sidc::destroydbox schreibe
*/
    gtk_container_add(GTK_CONTAINER(dbox), dtable);
    gtk_widget_show_all(dbox);
    gtk_main();
}



Meine sidc.h
Code:
	#ifndef _sidcH_
    #define _sidcH_

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>

using namespace std;

class sidc {
    private:
        GtkWidget *window, *table, *text, *label1, *gvname, *gname, *gstrasse, *ghnr, *gplz, *gort, *gtfon, *gtut, *ok, *dbox, *dok, *dtext, *dtable;
        fstream temp, students;
    public:
        sidc();
        void toggle_button_callback(GtkWidget *widget, gpointer data);
        void destroy(GtkWidget *widget, gpointer data);
        void destroydbox(GtkWidget *widget, gpointer data);
        void already_exist();
        void success();
};

#endif


...wenn ich das jetzt aber kompilieren will kommt immer der Fehler bei allen voids wo ich &sidc:: schreibe...

Code:
Fehler: Umwandlung von »void (sidc::*)(GtkWidget*, void*)« nach »void (*)()«


Hoffe mir kann jemand sagen was ich falsch mache.

danke im voraus
 
Hi.

Die Typen sind unverträglich. Man kann nicht einen Zeiger einer Member-Funktion (Methode) einer Klasse als Zeiger auf eine Funktion übergeben. Um eine (nicht-statische) Methode aufzurufen, benötigt man immer eine Instanz der Klasse. Deswegen nützt der Zeiger zur Methode ohne eine Instanz rein gar nichts.

Wenn du objektorientiert mit Gtk+ programmieren willst, dann schau dir mal gtkmm an.

Alternativ könntest du alle Methoden, die du als Callback-Funktionen verwenden willst, als static" deklarieren. Dann brauchst du allerdings auch keine Klassen verwenden.

Gruß
 
C++:
class sidc {
    public:
        static void destroydbox(GtkWidget *widget, gpointer data);
}

gtk_signal_connect(GTK_OBJECT(dok), "clicked",
    GTK_SIGNAL_FUNC( sidc::destroydbox ), NULL );
Wie gesagt, das ganze ist so relativ unsinnig.

Gruß
 
ok, danke, ich habe das jetzt umgeändert und folgende Fehler beim compilieren:

sidc.cpp:101: Fehler: Elementfunktion »void sidc::destroy(GtkWidget*, void*)« kann nicht deklariert werden, statische Bindung zu haben
sidc.h: In static member function »static void sidc::destroydbox(GtkWidget*, void*)«:
sidc.h:14: Fehler: ungültige Verwendung des Elementes »sidc::dbox« in statischer Elementfunktion
sidc.cpp:106: Fehler: von dieser Stelle

Mein sidc.cpp von Zeile 101 bis 107:
Code:
static void sidc::destroy(GtkWidget *widget, gpointer data) {
	gtk_widget_destroy(window);
}

void sidc::destroydbox(GtkWidget *widget, gpointer data){
	gtk_widget_destroy(dbox);
}

und sidc.h Zeile 10 bis 23
Code:
using namespace std;

class sidc {
	private:
		GtkWidget *window, *table, *text, *label1, *gvname, *gname, *gstrasse, *ghnr, *gplz, *gort, *gtfon, *gtut, *ok, *dbox, *dok, *dtext, *dtable;
		fstream temp, students;
	public:
		sidc();
		void toggle_button_callback(GtkWidget *widget, gpointer data);
		void destroy(GtkWidget *widget, gpointer data);
		static void destroydbox(GtkWidget *widget, gpointer data);
		void already_exist();
		void success();
};

Ich hoffe jemand kann mir helfen, danke

gruß
 
ok, danke, ich habe das jetzt umgeändert und folgende
Mein sidc.cpp von Zeile 101 bis 107:
Code:
static void sidc::destroy(GtkWidget *widget, gpointer data)
Du darfst hier das Schlüsselwort "static" nicht wiederholen, da es an dieser Stelle eine andere Bedeutung hat als innerhalb der Klassendefinition.

Desweiteren kannst du selbstverständlich in statischen Methoden einer Klasse nicht auf Attribute einer Klasse zugreifen - es sei denn, sie sind auch statisch.

Gtk+ ist nunmal eine C Bibliothek (die in der Form ja auch "objektorientierte" Techniken verwendet), also sollte man diese auch auf die übliche Art und Weise verwenden. Du versuchst irgendwie auf Biegen und Brechen C++ Sprachmittel wie Klassen und objektorientierte Konzepte zu nutzen. Das macht aber überhaupt keinen Sinn.

Ich kann dir nur empfehlen, Gtk+ "ganz normal" zu verwenden, oder die wirklich gute Wrapper-Bibliothek gtkmm zu verwenden.

Gruß
 
hi, also mein neues sidc.h lautet:

Code:
using namespace std;

class sidc {
	private:
		GtkWidget *window, *table, *text, *label1, *gvname, *gname, *gstrasse, *ghnr, *gplz, *gort, *gtfon, *gtut, *ok, *dbox, *dok, *dtext, *dtable;
		fstream temp, students;
	public:
		sidc();
		static void toggle_button_callback(GtkWidget *widget, gpointer data);
		static void destroy(GtkWidget *widget, gpointer data);
		static void destroydbox(GtkWidget *widget, gpointer data);
		static void already_exist();
		static void success();
};

und beim compilieren kommt:

Code:
sidc.h:14: Fehler: ungültige Verwendung des Elementes »sidc::gname« in statischer Elementfunktion

und das wiederholt sich für jede GtkWidget Vaiable.

sry, aber ich will nicht umbedingt auf gtkmm umlernen.

danke
 
Hi.
und beim compilieren kommt:

Code:
sidc.h:14: Fehler: ungültige Verwendung des Elementes »sidc::gname« in statischer Elementfunktion

und das wiederholt sich für jede GtkWidget Vaiable.
Wie ich bereits sagte, kann man aus einer statischen Methode nur auf statische Attribute einer Klasse zugreifen. D.h. die ganzen GtkWidget Variablen müssen auch statisch sein. Das führt dazu das sie extra außerhalb der Klasse definiert werden müssen:
C++:
class sidc {
private:
  static GtkWidget *window, *table, ...;
};

// .cpp Datei:

GtkWidget *sidc::window;
GtkWidget *sidc::table;
...
sry, aber ich will nicht umbedingt auf gtkmm umlernen.
Dann verwende Gtk+. Man programmiert noch lange nicht objektorientiert, nur weil man objektorientierte Sprachmittel einsetzt.

Gruß
 
okay vielen dank. Jetzt läuft alles. Es ist compilerbar, nur wenn ich es aussführe, dann kommt:

Code:
(<unknown>:3676): Gtk-CRITICAL **: gtk_table_attach: assertion `child->parent == NULL' failed

(<unknown>:3676): Gtk-CRITICAL **: gtk_table_attach: assertion `child->parent == NULL' failed
Speicherzugriffsfehler

Er müsste das ausfürhen:

Code:
lidc::lidc()
{
	gtk_init(FALSE,FALSE);
	table 	= gtk_table_new(16,4,FALSE);	
	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(window),"Lehrer hinzufuegen");
	text = gtk_label_new("Name");
	gtk_table_attach(GTK_TABLE(table),text,0,1,0,1,GTK_FILL, GTK_FILL,2,2);
	text = gtk_label_new("Vorname");
	gtk_table_attach(GTK_TABLE(table),text,2,3,0,1,GTK_FILL, GTK_FILL,2,2);
	text = gtk_label_new("Strasse/Hausnummer");
	gtk_table_attach(GTK_TABLE(table),text,0,1,1,2,GTK_FILL, GTK_FILL,2,2);
	text = gtk_label_new("PLZ/Ort");
	gtk_table_attach(GTK_TABLE(table),text,0,1,2,3,GTK_FILL, GTK_FILL,2,2);
	text = gtk_label_new("Telefonnummer");
	gtk_table_attach(GTK_TABLE(table),text,0,1,3,4,GTK_FILL, GTK_FILL,2,2);
	text = gtk_label_new("Kuerzel");
	gtk_table_attach(GTK_TABLE(table),text,2,3,3,4,GTK_FILL, GTK_FILL,2,2);
	gname = gtk_entry_new();
	gtk_table_attach(GTK_TABLE(table),gname,1,2,0,1,GTK_FILL, GTK_FILL,2,2);
	gvname = gtk_entry_new();
	gtk_table_attach(GTK_TABLE(table),gvname,3,4,0,1,GTK_FILL, GTK_FILL,2,2);
	gstrasse = gtk_entry_new();
	gtk_table_attach(GTK_TABLE(table),gstrasse,1,3,1,2,GTK_FILL, GTK_FILL,2,2);
	ghnr = gtk_entry_new();
	gtk_table_attach(GTK_TABLE(table),ghnr,3,4,1,2,GTK_FILL, GTK_FILL,2,2);
	gplz = gtk_entry_new();
	gtk_table_attach(GTK_TABLE(table),gplz,1,2,2,3,GTK_FILL, GTK_FILL,2,2);
	gort = gtk_entry_new();
	gtk_table_attach(GTK_TABLE(table),gort,2,4,2,3,GTK_FILL, GTK_FILL,2,2);
	gtfon = gtk_entry_new();
	gtk_table_attach(GTK_TABLE(table),gtfon,1,2,3,4,GTK_FILL, GTK_FILL,2,2);
	gk = gtk_entry_new();
	gtk_table_attach(GTK_TABLE(table),gname,3,4,3,4,GTK_FILL, GTK_FILL,2,2);
	text	= gtk_hseparator_new();
	gtk_table_attach(GTK_TABLE(table), text, 0, 4, 4, 5, GTK_FILL, GTK_FILL, 2, 2);
	text = gtk_label_new("Bitte die Faecher eingeben");
	gtk_table_attach(GTK_TABLE(table),text,0,4,5,6,GTK_FILL, GTK_FILL,2,2);
	deu = gtk_check_button_new_with_label("Deutsch");
	gtk_table_attach(GTK_TABLE(table), deu, 0, 1, 6, 7, GTK_FILL, GTK_FILL, 2, 2);
	eng = gtk_check_button_new_with_label("Englisch");
	gtk_table_attach(GTK_TABLE(table), eng, 0, 1, 7, 8, GTK_FILL, GTK_FILL, 2, 2);
	frz = gtk_check_button_new_with_label("Franzoesisch");
	gtk_table_attach(GTK_TABLE(table), frz, 0, 1, 8, 9, GTK_FILL, GTK_FILL, 2, 2);
	spa = gtk_check_button_new_with_label("Spanisch");
	gtk_table_attach(GTK_TABLE(table), spa, 0, 1, 9, 10, GTK_FILL, GTK_FILL, 2, 2);
	ku = gtk_check_button_new_with_label("Kunst");
	gtk_table_attach(GTK_TABLE(table), ku, 0, 1, 10, 11, GTK_FILL, GTK_FILL, 2, 2);
	mu = gtk_check_button_new_with_label("Musik");
	gtk_table_attach(GTK_TABLE(table), mu, 0, 1, 11, 12, GTK_FILL, GTK_FILL, 2, 2);
	ds = gtk_check_button_new_with_label("Darstellendes Spiel");
	gtk_table_attach(GTK_TABLE(table), deu, 0, 1, 12, 13, GTK_FILL, GTK_FILL, 2, 2);
	pw = gtk_check_button_new_with_label("Politik und Wirtschaft");
	gtk_table_attach(GTK_TABLE(table), pw, 1, 2, 6, 7, GTK_FILL, GTK_FILL, 2, 2);
	ge = gtk_check_button_new_with_label("Geschichte");
	gtk_table_attach(GTK_TABLE(table), ge, 1, 2, 7, 8, GTK_FILL, GTK_FILL, 2, 2);
	rek = gtk_check_button_new_with_label("katholische Religion");
	gtk_table_attach(GTK_TABLE(table), rek, 1, 2, 8, 9, GTK_FILL, GTK_FILL, 2, 2);
	reev = gtk_check_button_new_with_label("evangelische Religion");
	gtk_table_attach(GTK_TABLE(table), reev, 1, 2, 9, 10, GTK_FILL, GTK_FILL, 2, 2);
	eth = gtk_check_button_new_with_label("Ethik");
	gtk_table_attach(GTK_TABLE(table), eth, 1, 2, 10, 11, GTK_FILL, GTK_FILL, 2, 2);
	ma = gtk_check_button_new_with_label("Mathematik");
	gtk_table_attach(GTK_TABLE(table), ma, 2, 3, 6, 7, GTK_FILL, GTK_FILL, 2, 2);
	bio = gtk_check_button_new_with_label("Biologie");
	gtk_table_attach(GTK_TABLE(table), bio, 2, 3, 7, 8, GTK_FILL, GTK_FILL, 2, 2);
	che = gtk_check_button_new_with_label("Chemie");
	gtk_table_attach(GTK_TABLE(table), che, 2, 3, 8, 9, GTK_FILL, GTK_FILL, 2, 2);
	phy = gtk_check_button_new_with_label("Physik");
	gtk_table_attach(GTK_TABLE(table), phy, 2, 3, 9, 10, GTK_FILL, GTK_FILL, 2, 2);
	info = gtk_check_button_new_with_label("Informatik");
	gtk_table_attach(GTK_TABLE(table), info, 2, 3, 10, 11, GTK_FILL, GTK_FILL, 2, 2);
	spo = gtk_check_button_new_with_label("Sport");
	gtk_table_attach(GTK_TABLE(table), spo, 3, 4, 6, 7, GTK_FILL, GTK_FILL, 2, 2);	
	text	= gtk_hseparator_new();
	gtk_table_attach(GTK_TABLE(table), text, 0, 4, 13, 14, GTK_FILL, GTK_FILL, 2, 2);
	GtkWidget *ok, *cl;
	ok = gtk_button_new_with_label("OK");
	gtk_table_attach(GTK_TABLE(table), ok, 2, 3, 14, 15, GTK_EXPAND, GTK_FILL, 2, 2);
	gtk_signal_connect(GTK_OBJECT(ok),"clicked",GTK_SIGNAL_FUNC(lidc::ok_button_callback), NULL);
	cl = gtk_button_new_with_label("Schliessen");
	gtk_table_attach(GTK_TABLE(table), cl, 3, 4, 14, 15, GTK_EXPAND, GTK_FILL, 2, 2);
	gtk_signal_connect(GTK_OBJECT(close),"clicked",GTK_SIGNAL_FUNC(lidc::destroy), NULL);
	gtk_container_add(GTK_CONTAINER(window), table);
	gtk_widget_show_all(window);
	gtk_main();
	
}

Wo liegt der Fehler? danke im voraus
 
okay vielen dank. Jetzt läuft alles. Es ist compilerbar, nur wenn ich es aussführe, dann kommt:

Code:
(<unknown>:3676): Gtk-CRITICAL **: gtk_table_attach: assertion `child->parent == NULL' failed

(<unknown>:3676): Gtk-CRITICAL **: gtk_table_attach: assertion `child->parent == NULL' failed
Speicherzugriffsfehler
Du hast offensichtlich versucht ein Widget in die Tabelle einzufügen, welches bereits einem anderen Container zugewiesen war.

Du solltest einen Debugger verwenden um die Stelle konkret zu lokalisieren. Oder den Code nochmal kontrollieren...

Gruß
 
Zurück