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

C, C#, C++ - Wskaźnik na metodę / delegat / event

Madman07 - 12-07-2012, 11:37
Temat postu: 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();
}

piotrdz - 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 - 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++.

piotrdz - 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 - 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 :) )


Powered by phpBB modified by Przemo & WRIM © 2003 phpBB Group