PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Objektorientiertes Design



Linuxexplorer
29-12-2002, 12:53
Im Buch "Linux 3D Grafik Programmierung" beschreibt der Autor ein einfach X-programm, zuerst nicht objektorientiert, dann mir Klassen. Leider habe voll den Durchlick verloren, denn bei einer Zeile im Code verstehe ich nichts!

Hier ist der Code

ch2_app.h


#ifndef __CH2_APP_H
#define __CH2_APP_H

#include <stdio.h>

class ch2_app {
protected:
virtual void create_window(void) = 0;
virtual void ask_to_be_notified_of_interesting_events(void) = 0;
virtual void event_loop(void) = 0;

public:
virtual ~ch2_app(void) {};
virtual void execute(void);
};
#endif



ch2_app.cc


#include "ch2_app.h"

//sbegin execute
void ch2_app::execute(void) {
create_window();
ask_to_be_notified_of_interesting_events();
event_loop();
}
//send execute



ch2_app_x.h


#ifndef __CH2_APP_X_H
#define __CH2_APP_X_H
#include "ch2_app.h"
#include <X11/Intrinsic.h>
#include <X11/Xlib.h>

class ch2_app_x : public ch2_app {
protected:
const static int screen_xsize = 320;
const static int screen_ysize = 200;
Visual *vis; // X11: Visual (visual info about X server)
Display *dpy; // X11: Display (connection to X server)
Window w; // X11: Window

void create_window(void); // virtual
void ask_to_be_notified_of_interesting_events(void); // virtual
void event_loop(void); // virtual

public:
virtual ~ch2_app_x(void) {};
};
#endif



ch2_app_x.cc


#include "ch2_app_x.h"
#include <stdio.h>
#include <stdlib.h>

void ch2_app_x::create_window(void) {

// establish connection to X server

dpy = XOpenDisplay(NULL);

// create and map (display) an X window for output

vis = DefaultVisual(dpy,0);
w = XCreateWindow(dpy, // display
DefaultRootWindow(dpy), // parent
100, 100, // x, y position
screen_xsize, screen_ysize, // width, height
0, // border width
CopyFromParent, // depth (we use max. possible)
CopyFromParent, // visual class (TrueColor etc)
vis, // visual
0, NULL); // valuemask, window attributes

XMapWindow(dpy, w);
}

void ch2_app_x::ask_to_be_notified_of_interesting_event s(void) {
XSelectInput(dpy, w, KeyPressMask);
}

void ch2_app_x::event_loop(void) {
XEvent event;
char ch;
KeySym keysym;
XComposeStatus xcompstat;

while(1) {
if(XCheckWindowEvent(dpy,w,KeyPressMask,&event)) {
XLookupString(&event.xkey, &ch, 1, &keysym, &xcompstat);
switch(ch) {
case 'q': {
exit(0);
}
}
}
}
}


ch2_appfactory.h


#ifndef __CH2_APPFACTORY_H
#define __CH2_APPFACTORY_H

#include "ch2_app.h"

//sbegin abstract_create
class ch2_appfactory {
public:
virtual ch2_app *create(void) = 0;
};
//send abstract_create

#endif



ch2_appfactory_x.h

#ifndef __CH2_APPFACTORY_X_H
#define __CH2_APPFACTORY_X_H

#include "ch2_appfactory.h"

class ch2_appfactory_x : public ch2_appfactory {
ch2_app *create(void);
};
#endif



ch2_appfactory_x.cc


#include "ch2_appfactory_x.h"
#include "ch2_app_x.h"

//sbegin x_create
ch2_app *ch2_appfactory_x::create(void) {
return new ch2_app_x;
}
//send x_create


ch2_factorymanager.h


#ifndef __CH2_FACTORYMANAGER_H
#define __CH2_FACTORYMANAGER_H
#include "ch2_appfactory.h"

class ch2_factorymanager {
public:
static ch2_appfactory *appfactory;
void choose_factories(void);
};

#endif


ch2_factorymanager.cc


#include "ch2_factorymanager.h"

// references to concrete factories

#include "ch2_appfactory_x.h"


ch2_appfactory *ch2_factorymanager::appfactory = 0;

Hier ist mein Problem! Das geht doch gar nicht! In diesem Object (ch2_appfactory) gibt es doch gar kein appfactory-Object, dass wird ja in ch2_factorymanager erzeugt und nicht in ch2_appfactory. Das Programm funktioniert aber trotzdem! Ich begreife das nicht !

void ch2_factorymanager::choose_factories(void) {
int i;

printf("Welche Appfactory soll die Anwendung erzeugen?\n");
printf("1. Appfactory erzeugt eine einfache X-Anwendung\n");

scanf("%d", &i);

switch(i) {
case 1: {
appfactory = new ch2_appfactory_x;
};
break;
}
}



ch2_hello.cc


#include "ch2_factorymanager.h"

//sbegin fm_declare
main() {
ch2_app *application;
ch2_factorymanager fm;
//send fm_declare

//sbegin choose_fac
fm.choose_factories();
//send choose_fac
//sbegin create_and_go
application = fm.appfactory->create(); // virtual function call
application->execute(); // virtual function call
}
//send create_and_go

tkortkamp
29-12-2002, 14:09
Hi!
appfactory ist static, d.h. du musst es einmal initialisieren.


class ch2_factorymanager {
public:
static ch2_appfactory *appfactory;
void choose_factories(void);
};

Das wird hiermit gemacht:


ch2_appfactory *ch2_factorymanager::appfactory = 0;

ch2_appfactor ist hier nur der Typ der Variable wie sie auch in der Klassendeklaration angegeben wurde. Davon darfst du dich nicht verwirren lassen :) Weil appfactory aus ch2_factorymanager ja statisch ist musst du es einmal außerhalb und nicht erst im Konstruktor initaliersieren (es ist ja immer da). Der Zugriff auf diese Variable erfolgt mit ch2_factorymanager::appfactory also <Klassenname>::<Variable>

Hmm, hoffe das du jetzt mehr durchsteigst.

c ya,
Tobias

Linuxexplorer
29-12-2002, 17:19
Hi tkortkamp !

Jetzt habe ich's gechekt! :D Vielen Dank!

MFG: Linuxexplorer