Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    [C++] acesso ai dati di una classe

    Ho definito una classe così:

    codice:
    class line 
    {
    	public: 
    		line(char*, char*, int, int, int, int, int);
    		void SetTextColor(float,float,float);
    		bool Step(cairo_t*);
    	private:		
    		cairo_matrix_t matrix, backupmatrix;
    		int fade_in_max, stay_on_max, fade_out_max;
    		float fade_in_step, fade_out_step;
    		int current_step;
    		int max_transform_y, max_transform_x;
    		float transform_x_step, transform_y_step;
    
    		char* text;
    		char* author; 
    		int win_x, win_y;		
    
    		void Draw(cairo_t*);
    		void GetRows(cairo_t*);
    		float colormatrix[4];
    		float size;
    		char font[100];
    		int numrows;
    		struct row_t
    		{
    			int x;
    			int y;
    			char text[100];
    		} rows[50];
    };
    il problema è che quando da una delle due funzioni Step() oppure SetTextColor() tento di accedere a una delle proprietà della classe.. (ad esempio colormatrix, o qualunue altra) mi da segfault... (solo in quel momento, non prima)

    questo è il codice che chiama la Step(), ho provato anche chiamando SetTextColor() e fa la stessa cosa...

    codice:
    #include <string.h>
    #include <stdlib.h>
    #include <cairo.h>
    #include <gtk/gtk.h>
    #include "lineclass.h"
    #include "clientp.h"
    
    GtkWidget *window;
    line *text;
    
    
    static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
    {
    	cairo_t *cr;
    	cr = gdk_cairo_create(widget->window);
    
    	int w,h;	
    	gtk_window_get_size(GTK_WINDOW(widget), &w, &h);
    
    	cairo_set_source_rgb(cr, 1,1,1); //clear the screen
    	cairo_rectangle(cr, 0,0,w,h); 
    	cairo_set_line_width(cr, 10);
    	cairo_stroke_preserve(cr);
    	cairo_fill(cr);
    
    	text->Step(cr);                                                  //****** chiamata incriminata
    
    	cairo_destroy(cr);
    	return FALSE;
    }
    
    gboolean TimerFunc(void*)
    {
    	gtk_widget_queue_draw(window);
    	return TRUE;
    }
    
    int main (int argc, char *argv[])
    {
    	srand(time(NULL));
    
    	gtk_init(&argc, &argv);
    	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    	gtk_window_set_title(GTK_WINDOW(window), "KP's ClientP");
    	gtk_window_set_default_size(GTK_WINDOW(window), 1024, 768); 
    	g_signal_connect(window, "expose-event", G_CALLBACK (on_expose_event), NULL);
    	g_signal_connect(window, "destroy",G_CALLBACK (gtk_main_quit), NULL);
    	gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    	gtk_widget_set_app_paintable(window, TRUE);
    	gtk_widget_show_all(window);
    
    	g_timeout_add(80, TimerFunc, NULL); 
    
    	line *text = new line("prova", "prova", 924, 678, 30, 30, 30);  //*************** qui creo l'oggetto
    	gtk_main();
    
    	return 0;
    }
    grazie a tutti

  2. #2
    Utente di HTML.it
    Registrato dal
    Dec 2004
    Messaggi
    286
    Hai provato a dichiarare colormatrix sotto lo specificatore d'accesso "public :"?

  3. #3
    Nello specifico non ho preovato, ma il problema non si presenta solo con colormatrix, ma con qualsiasi altra proprietà a cui tento di accedere (con le funzioni non lo fa).
    In ogni caso io tento di accedere a colormatrix da una funzione di quella classe, che dovrebbe vedere tranquillamente anche le variabili private (infatti il compialtore non da errori).

    Quello che penso io è che l'oggetto text risulti come non allocato, e quindi, quando prova a leggere i dati va in segfault. Il fatto è che io l'ho allocato chiamando il costruttore nel main!

  4. #4
    Utente di HTML.it
    Registrato dal
    Dec 2004
    Messaggi
    286
    Originariamente inviato da Infernal In ogni caso io tento di accedere da una funzione di quella classe, che dovrebbe vedere tranquillamente anche le private.
    Si, infatti se l'accesso all'attributo privato non è diretto ma avviene attraverso l'invocazione di metodi pubbici della classe, allora va bene.


    Originariamente inviato da Infernal Quello che penso io è che l'oggetto text risulti come non allocato, e quindi, quando prova a leggere i dati va in segfault. Il fatto è che io l'ho allocato chiamando il costruttore nel main!
    Dovrei compilare il codice sul mio compilatore per capire cosa non va del tuo cdice, ma dando una veloce occhiata mi sembra di capire che gli attributi come colormatrix sono solo dichiarati, ma non inizializzati. Potrebbe essere questo il problema. Potresti inizializzare queste variabili nel corpo del costruttore.

  5. #5
    Si, sono inizializati, solo che non ho postato tutto il codice perchè +è lunghetto.. =) questo è tutto il resto:

    codice:
    #include <iostream>
    #define FONT "Sans"
    #define TEXTFACTOR 0.8
    #define AUTHORSCALEFACTOR 0.7
    #define MAX_TRANSFORM_X 100
    #define MAX_TRANSFORM_Y 100
    
    class line 
    {
    	public: 
    		line(char*, char*, int, int, int, int, int);
    		void SetTextColor(float,float,float);
    		bool Step(cairo_t*);
    	private:		
    		cairo_matrix_t matrix, backupmatrix;
    		int fade_in_max, stay_on_max, fade_out_max;
    		float fade_in_step, fade_out_step;
    		int current_step;
    		int max_transform_y, max_transform_x;
    		float transform_x_step, transform_y_step;
    
    		char* text;
    		char* author; 
    		int win_x, win_y;		
    
    		void Draw(cairo_t*);
    		void GetRows(cairo_t*);
    		float colormatrix[4];
    		float size;
    		char font[100];
    		int numrows;
    		struct row_t
    		{
    			int x;
    			int y;
    			char text[100];
    		} rows[50];
    };
    
    line::line(char *textin, char *authorin, int width, int height, int fade_in, int stay_on, int fade_out)
    {
    	text = (char*) malloc(sizeof(char) * (strlen(textin) + 1)); //allocating space for the text and author
    	author = (char*) malloc(sizeof(char) * (strlen(authorin) + 1));
    	strcpy(text, textin); //copy the input strings into the private string
    	strcpy(author, authorin); 
    
    	colormatrix[0] = 0; //default text color black 
    	colormatrix[1] = 0;
    	colormatrix[2] = 0;
    	colormatrix[4] = 1;
    	size = 50.0;
    	strcpy(font, FONT);
    	numrows = 0;
    	win_x = height;
    	win_y = width;
    
    	fade_in_max = fade_in;
    	stay_on_max = stay_on;
    	fade_out_max = fade_out;
    	fade_in_step = 1/fade_in_max;                  //calculate the speed of fade in effect, the more the total effect time, the less the step;
    	fade_out_step = 1/fade_out_max; //calculate the speed of fade in effect, the more the total effect time, the less the step;
    	current_step = 0;
    	
    	max_transform_y = (rand()%(2*MAX_TRANSFORM_Y)) - MAX_TRANSFORM_Y; //generate transformation matrix, we allow negative translations.
    	max_transform_x = (rand()%(2*MAX_TRANSFORM_X)) - MAX_TRANSFORM_X;
    
    	transform_x_step = max_transform_x/fade_in_max+stay_on_max+fade_out_max; //calculate the speed of translation, total distance / total steps
    	transform_y_step = max_transform_y/fade_in_max+stay_on_max+fade_out_max;
    	
    	cairo_matrix_init_identity(&matrix);
    }
    
    bool line::Step(cairo_t *cr)
    {	
    	cairo_get_matrix(cr, &backupmatrix); //make a backup copy of the current matrix
    	cairo_set_matrix(cr, &matrix); //use our matrix 
    
    	if (current_step < fade_in_max)
    	{	puts(cairo_status_to_string(cairo_status(cr)));
    		colormatrix[3] += fade_in_step;
    		cairo_translate(cr, transform_x_step, transform_y_step);
    	}
    	else if (current_step - fade_in_max < stay_on_max)
    	{
    		cairo_translate(cr, transform_x_step, transform_y_step);
    	}
    	else if (current_step - fade_in_max - stay_on_max < fade_out_max)
    	{
    		colormatrix[3] -= fade_out_step;
    		cairo_translate(cr, transform_x_step, transform_y_step);
    	}
    	else return false;
    	
    	Draw(cr);
    
    	cairo_get_matrix(cr, &matrix); //save our matrix
    	cairo_set_matrix(cr, &backupmatrix); // reset the backup matrix
    	current_step++;
    }
    
    void line::SetTextColor(float r, float g, float b)
    {
    	if (r > 1) r = 1; //max and min value for the colormatrix
    	if (r < 0) r = 0;
    	if (g > 1) g = 1;
    	if (g < 0) g = 0;
    	if (b > 1) b = 1;
    	if (b < 0) b = 0;
    
    	colormatrix[0] = r; //update colormatrix with new values
    	colormatrix[1] = g;
    	colormatrix[2] = b;
    }
    
    void line::GetRows(cairo_t *cr)               
    {
    	char *buff;
    	int x,y;
    	int y_size = 0;
    	cairo_text_extents_t extents;
    	cairo_text_extents_t buffextents;
    	cairo_select_font_face(cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
    	cairo_set_font_size(cr, size);
    	buff = strtok(text, " ");		//get the frist tok and copy it in the frsit line
    	strcpy(rows[numrows].text, buff);
    	strcat(rows[numrows].text, " ");
    	while(1)
    	{
    		buff = strtok(NULL, " ");	//get a new tok
    
    		if (buff == NULL) break; //if we've reached the end exit the while
    		
    		cairo_text_extents(cr, rows[numrows].text, &extents); //lenght of the current row
    		cairo_text_extents(cr, buff, &buffextents);
    		if (extents.width + buffextents.width > win_x*TEXTFACTOR) //if the row is too wide use another row
    		{
    			y_size += extents.height; //increase the text global heighth
    			numrows++; //change the current row
    			strcpy(rows[numrows].text, buff); //write buff
    			strcat(rows[numrows].text, " ");	
    		}
    
    		else 
    		{
    			strcat(rows[numrows].text, buff); //append buff at the row
    			strcat(rows[numrows].text, " ");
    		}
    	}
    	numrows++; //numrows starts form 0, we have to add 1 to get the real number of rows
    
    	int y_start = (win_y-y_size)/2; //the starting printing pos
    	for (int i = 0; i < numrows; i++) //for each row
    	{
    		cairo_text_extents(cr, rows[i].text, &extents); //calculate the printing pos of each row	
    		rows[i].x = (win_x - extents.width)/2;
    		rows[i].y = y_start;
    		y_start += extents.height + size/4;
    	}
    }
    
    void line::Draw(cairo_t *cr)
    {
    	GetRows(cr); //Split the text in varous rows;
    	int w,h;
    	cairo_set_source_rgba(cr, colormatrix[0], colormatrix[1],colormatrix[2], colormatrix[3]); //setup text rendering
    	cairo_select_font_face(cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
    	cairo_set_font_size(cr, size);	
    
    	for (int i = 0; i < numrows; i++) //print each row
    	{
    		cairo_move_to(cr, rows[i].x, rows[i].y);
    		cairo_show_text(cr, rows[i].text);
    	}
    
    	cairo_text_extents_t extents; //Print the author string;
    	cairo_set_font_size(cr, size*AUTHORSCALEFACTOR);	
    	cairo_text_extents(cr, author, &extents);
    	int x,y;
    	x = (w-extents.width)*0.80;
    	y = (h+rows[numrows-1].y)/2;
    
    	cairo_move_to(cr, x, y);
    	cairo_show_text(cr, author);
    }

    edit:

    questo è il codice di lineclass.h che includo dal main. La riga che include clientp.h puoi toglerla, è un atrlo pezzo di codice dove funziona tutto...

  6. #6
    Ok scusatemi... mi rendo conto di essere un cretino...
    nel main ridichiaravo text... quindi io inizializzavo la variabile del main e non quella globale, che ovviamente dava segfault perchè non esisteva.

    odio questi errori subdoli!!!!


    grazie a tutti... =)

  7. #7
    Originariamente inviato da Infernal
    odio questi errori subdoli!!!!
    L'errore che tu chiami subdolo te lo sei cercato tu nell'utilizzo indiscriminato di variabili globali, con l'aggravante di non aver usato identificatori o namespace significativi che evidenzino la loro globalità.

    Soluzione?
    • Non usare variabili globali;
    • Se proprio devi usarne, dagli un identificatore o un namespace significativo.

    ;-)

  8. #8
    è che sono così comode... comunque penso seguirò il tuo consiglio nei prossimi programmi..

    thanks

    edit: fra l'altro ho notato che l'altra variabile globale non la uso nemmeno... provvedo a toglierla...


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.