Oryginalna strona colobot.cba.pl umarła, gdy cba.pl przestało oferować darmowy hosting. To jest statyczny mirror, pobrany w 2018. ~krzys_h
 Polski Portal COLOBOTa - COLOBOT Polish Portal
Forum - Polski Portal COLOBOTa
Strona głównaStrona główna UżytkownicyUżytkownicy GrupyGrupy StatystykiStatystyki


Poprzedni temat «» Następny temat
Wskaźnik na metodę / delegat / event
Autor Wiadomość
Madman07


Wiek: 28
Dołączył: 29 Maj 2011
Posty: 133
Skąd: Ze Stargate ;]
Wysłany: 12-07-2012, 11:37   Wskaźnik na metodę / delegat / event

Witam.

Powiedzmy że mamy dwie klasy w różnych plikach, klasę DSS (główną) i GAME (mniej główną). Klasa DSS jest wywoływana z main, a GAME jest z DSS. W jaki sposób w klasie GAME odwołać się do metody klasy DSS? Nie wchodzi tu w grę metoda statyczna, ponieważ metoda musi być wywołana na obiekcie (mam nadzieję, że dobrze tłumaczę). Czyli to, co potrzebuję to coś w stylu delegata/eventu ale BEZ używania róznych bibliotek (jak Fast Delegates, Boost, CLR), bo potrzebuję to dosłownie na jeden raz. Albo jeszcze prościej, jak przekazać do klasy GAME wskaźnik na metodę klasy DSS?

A tu kod obrazujący to, co chcę zrobić:

Kod:
class DSS
{
public:
    DSS(void);
    ~DSS(void) {;};
    StartGame() {;}; 
}

DSS::DSS()
{
   GAME *mGame = new GAME();
}


Kod:

class GAME
{
public:
    GAME(void) {;};
    ~GAME(void) {;};
    ButtonClicked();
}

// to jest wywoływane przez pewną bibliotekę GUI
void GAME::ButtonClicked()
{
    // mDSS to właśnie instancja klasy DSS czyli to, co mogę otrzymać poprzez wskaźnik this w klasie DSS
    mDSS->StartGame();
}
_________________

"The Destiny. Launched hundreds of thousands of years ago. Faster than light, yet not through hyperspace. Who knows how far it's traveled."
 
     
piotrdz 


Twoja ulubiona misja: programowanie ;)
Pomógł: 1 raz
Dołączył: 17 Mar 2012
Posty: 55
Skąd: Częstochowa
Wysłany: 12-07-2012, 17:27   

Hm. Nie rozumiem do końca, w czym problem. W klasie GAME dodajesz jako pole wskażnik na obiekt DSS i wywołujesz metodę na nim. Zresztą w kodzie tak masz: mDSS->StartGame(). Musisz tylko dodać przed klasą deklarację wprzód, że taka klasa istnieje: class DSS;
A jak chcesz wskaźnik na metodę, to też możesz taki przekazać. Składnia jest trochę skomplikowana, ale w w literaturze znajdziesz.
 
 
     
Madman07


Wiek: 28
Dołączył: 29 Maj 2011
Posty: 133
Skąd: Ze Stargate ;]
Wysłany: 12-07-2012, 17:42   

Ok, zatem zrobiłem jak mówisz, jednak kompilator zaczął się rzucać. Masa błędów, w tym "DSS class redefinition". Nie wiem czy dobrze zauważyłeś, ale mGame jest wywołane z mDSS, nie na odwrót, taka sobie funkcja zwrotna.

Kod:
class DSS
{
public:
    DSS(void);
    ~DSS(void) {;};
    StartGame() {;}; 
}

DSS::DSS()
{
   GAME *mGame = new GAME(this);
}


Kod:

class DSS {};

class GAME
{
public:
    GAME(void) {DSS *mDSS};
    ~GAME(void) {;};
    ButtonClicked();

    DSS *mDSS;
}

void GAME::ButtonClicked()
{
    mDSS->StartGame();
}


Edit:
Hmm, z drugiej strony mógłbym wypieprzyć te klasy bo i tak w całej grze będę miał tylko jeden obiekt klasy DSS i jeden obiekt klasy game. A tak o wiele łatwiej by było. Hmm, chyba tak zrobię, co się jednak niby mija z obektowością języka C++.
_________________

"The Destiny. Launched hundreds of thousands of years ago. Faster than light, yet not through hyperspace. Who knows how far it's traveled."
 
     
piotrdz 


Twoja ulubiona misja: programowanie ;)
Pomógł: 1 raz
Dołączył: 17 Mar 2012
Posty: 55
Skąd: Częstochowa
Wysłany: 12-07-2012, 20:29   

Myślałem, że kod masz rozbity na .h i .cpp i tylko tak wklejasz.
No to jeszcze raz:

game.h:
Kod:

#pragma once

class DSS; // bez {}
// class foo {}; oznacza deklarację pustej klasy (bez pól i metod)
// class foo; oznacza deklarację poprzedzającą (forward declaration)

class GAME
{
public:
    GAME(DSS *mDSS) { this->mDSS = mDSS; } // też chyba o to chodziło
    ~GAME() {}
    void ButtonClicked(); // brakowało void

    DSS *mDSS;
};


game.cpp:
Kod:

#include "game.h"
#include "dss.h"

void GAME::ButtonClicked()
{
    mDSS->StartGame();
}


dss.h
Kod:

#pragma once

class GAME; // ten sam manewr, co w dss.h
/* generalnie, jak w nagłówku jest tylko foo*, a nie foo (bez wskaźnika), nie trzeba do końca definiować foo - można dać tylko deklarację class foo; */

class DSS
{
public:
    DSS(); // void jest zbędne w C++
    ~DSS();
    void StartGame() { } // tu też zbędne średniki

    GAME *mGame; // chyba chodziło o pole - wnioskuję z przedrostku m...
}; // ale ten średnik jest obowiązkowy


dss.cpp:
Kod:

#include "dss.h"
#include "game.h"


DSS::DSS()
{
   mGame = new GAME(this); // j.w. - pole, nie zmienna lokalna
}

DSS::~DSS()
{
    delete mGame; // trzeba usunąć to, co zostało stworzone new
}
 
 
     
Madman07


Wiek: 28
Dołączył: 29 Maj 2011
Posty: 133
Skąd: Ze Stargate ;]
Wysłany: 12-07-2012, 21:16   

Tak, mam to porozbijanie na kilka plików, osobno .h, osobno .cpp i tak jak pisałem, gdzieś tutaj w temacie zapewne brakowało void, średników, destruktora itp., w kodzie to miałem.
Dzięki wielkie, własnie widzę miejsce, którego nie mogłem rozpracować. Zaraz biorę się do implementowania tego :) )
_________________

"The Destiny. Launched hundreds of thousands of years ago. Faster than light, yet not through hyperspace. Who knows how far it's traveled."
 
     
Wyświetl posty z ostatnich:   

Wersja do druku

Skocz do:  

Powered by phpBB modified by Przemo © 2003 phpBB Group
Polski Portal COLOBOTa © 2008 - 2012