Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Wywołanie w obiekcie metory z klasy tworzącej ten obiekt

Ostatnio zmodyfikowano 2018-01-16 21:53
Autor Wiadomość
setesh
Temat założony przez niniejszego użytkownika
Wywołanie w obiekcie metory z klasy tworzącej ten obiekt
» 2018-01-14 18:34:56
Witam,

mam taki nietypowy problem. Potrzebuję w nowoutworzonym obiekcie wywołać metodę z klasy w której jest tworzony. Niestety nie wiem jak się za to zabrać.
Może ktoś mnie nakierować na temat czy też pokazać co zmienić?

Ważne :
Tworząc w main.cpp obiekt klasy bazowa potrzebuję się odwoływać na tej zasadzie :
C/C++
bazowa * OBJ = new bazowa();
OBJ->o_pochodny->Narysuj( 14 );

Klasy :
C/C++
//--------------------------------------------------------------------------------------------------------

class c_pochodna
{
public:
    c_pochodna();
    Narysuj( int id );
};

//--------------------------------------------------------------------------------------------------------

class bazowa
{
public:
    bazowa();
    rysuj( int id_rysunku );
    c_pochodna * o_pochodny; // Nowy obiekt który ma wywołać metodę rysuj
};

//--------------------------------------------------------------------------------------------------------

bazowa::bazowa()
{
    o_pochodny = new c_pochodna();
}

//--------------------------------------------------------------------------------------------------------

c_pochodna::c_pochodna() { }

//--------------------------------------------------------------------------------------------------------

c_pochodna::Narysuj( int id )
{
    c_bazowa->rysuj( id ); // tu chce wywołać metodę z klasy tworzącej ten obiekt
}

Obecnie czytam o polimorfiźmie ale w międzyczasie bardzo liczę na waszą pomoc :)
P-168721
mateczek
» 2018-01-14 19:59:15
można ale robi się straszny zakręt

C/C++
#include<iostream>
using namespace std;
class bazowa;
class c_pochodna
{
public:
    bazowa * objBazowa;
    c_pochodna( bazowa * objBaz ) {
        objBazowa = objBaz;
    }
    void Narysuj( int id );
};


class bazowa
{
    c_pochodna * o_pochodny; // Nowy obiekt który ma wywołać metodę rysuj
public:
    bazowa() {
        o_pochodny = new c_pochodna( this ); // przekazujesz obiektowi pochodna wskaźnik na obiekt klasy bazowej
        o_pochodny->Narysuj( 23 ); //wywołujesz funkcje narysuj na obiekcie klasy pochodna
    }
   
    void rysuj( int id_rysunku ) {
        cout << "ale ciut zakręcone " << id_rysunku;
    }
   
};

void c_pochodna::Narysuj( int id ) {
    objBazowa->rysuj( id ); //funkcja "narysuj" obiektu klasy pochodna wywołuje funkcję "rysuj" na obiekcie przekazanym przez wskaźnik this
}
int main() {
    bazowa a;
}
P-168725
setesh
Temat założony przez niniejszego użytkownika
» 2018-01-14 20:31:26
Ok chyba jednak źle to poprojektowałem.

Mniej-więcej co chciałbym osiągnąć w pseudo-kodzie :

Mam klasę głowną w której są metody prywatne i publiczne.

C/C++
Klasax->prywatnaMetoda1
Klasax->prywatnaMetoda2

Klasax->publicznaMetoda1 // wywołuje prywatnaMetoda1
Klasax->publicznaMetoda2 // wywołuje prywatnaMetoda2
Klasax->publicznaMetoda3 // wywołuje prywatnaMetoda1
Klasax->publicznaMetoda4 // wywołuje prywatnaMetoda2
Klasax->publicznaMetoda5
Klasax->publicznaMetoda6 // wywołuje prywatnaMetoda2
Klasax->publicznaMetoda7 // wywołuje prywatnaMetoda1

Część publicznych metod chciałbym przenieść do nowego obiektu tak aby wyglądało to mniej więcej tak :

C/C++
Klasax->Obiekt1->metoda1 // Musi wywołać prywatnaMetoda1 z Klasax
Klasax->Obiekt1->metoda2 // Musi wywołać prywatnaMetoda2 z Klasax

Klasax->Obiekt2->metoda3 // Musi wywołać prywatnaMetoda1 z Klasax
Klasax->Obiekt2->metoda4 // Musi wywołać prywatnaMetoda2 z Klasax

Klasax->publicznaMetoda5
Klasax->publicznaMetoda6 // Musi wywołać prywatnaMetoda2 z Klasax
Klasax->publicznaMetoda7 // Musi wywołać prywatnaMetoda1 z Klasax

Problem w tym, że metody publiczne wywołują metody prywatne.
W momencie kiedy przeniosę je do nowego obiektu, muszą nadal mieć możliwość wywołania metod prywatnych.
Nie chce dla każdego obiektu tworzyć odpowiedników prywatnych metod więc przydałoby się jakieś "współdzielenie" metod.

I teraz zastanawiam się czy dobrze do tego podchodzę, bo wydaje mi się, że całkowicie niewłaściwie.

Możliwe, że Powinno się to zrobić na podstawie dziedziczenia klas ale nie chcę aby w jednej klasie były widoczne metody z innej.

Pytanie jest dość proste :
Czy da się osiągnąć efekt jaki chce korzystając z dziedziczenia (zachowując elementy xxx -> Obiekt1 -> yyy czyli Klasa -> Obiekt -> Metoda) ?
P-168727
mateczek
» 2018-01-14 22:13:21

Czy da się osiągnąć efekt jaki chce korzystając z dziedziczenia (zachowując elementy xxx -> Obiekt1 -> yyy czyli Klasa -> Obiekt -> Metoda) ?

raczej niejest to możliwe.
C/C++
Klasa->Obiekt->Metoda()
//takie coś jest niezgodne z c++ operator "->"  stosuje się do wskaźnika;

Klasa * wsk = new Klasa();
wsk->Obiekt.metoda();

Jeśli chcesz by obiekt podrzędny miał dostęp do obiektu nadrzędnego (koło miało dostęp do samochodu) to możesz mu przekazać go za pomocą wskaźnika this; Trochę można się w tym zakręcić ale czasami tak się robi. Nie wiem czy to dobry przykład ale coś tkiego na poczekaniu wymyśliłem
C/C++
#include<iostream>
class samochod;
using namespace std;
class kolo {
    samochod * parent; //rodzic dla obiektu koło
    int cisnienie = 3;
public:
    kolo( samochod * p )
        : parent( p )
    { }
    void test();
};


class samochod {
    kolo * k;
public:
    samochod() {
        k = new kolo( this ); //koło ma dostęp do auta za pomocą wskaźnika this. Do koła przypisujemy wskaźnik rodzica;
    }
    void chamuj() {
        cout << "hamowanie";
    }
    void testAuta();
};
void kolo::test() {
    if( cisnienie < 4 ) parent->chamuj(); //ciśnienie poniżej 4 wywoła funkcję samochód.hamuj()//wywołanie przez potomka funkcji rodzica;
    //koło wywołuje metodę chamuj() swojego właściciela;
}
void samochod::testAuta() {
    k->test(); //test koła
    //oczywiście lepszą metodą było by funkcja test zwracała zmienną
    // if(k->test()==false) hamuj();
}
int main()
{
    samochod s;
    s.testAuta();
}

Dziedziczenie służy temu by na klasie "Samochód" zrobić klasę "karetka pogotowia" czyli rozbudować sobie klasę o dodatkowe właściwości.
P-168738
mateczek
» 2018-01-15 04:49:48
ZAinteresuj się mechanizmem callbacków.
Dość fajnie rozwiązania calback ma biblioteka Qt. Słowa kluczowe dla google "Qt sygnały i sloty". Pozwolę sobie umieścić przykład:
C/C++
#ifndef KOLO_H
#define KOLO_H

#include <QObject>

class kolo
    : public QObject
{
    Q_OBJECT
    int cisnienie = 3;
public:
    explicit kolo( QObject * parent = nullptr ); //konstruktor
    signals:
    void awaria(); // w bibliotece Qt można sobie zadeklarować sygnał zostanie on wyemitowany
public slots:
};

#endif // KOLO_H
C/C++
#include "kolo.h"
#include<QTimer>
kolo::kolo( QObject * parent )
    : QObject( parent )
{
    //konstruktor koła. Wyemituje sygnał awarii dwie sekundy po stworzeniu obiektu koła 
    QTimer::singleShot( 2000, this, SIGNAL( awaria() ) ); //koło wyemituje awarie po 2 sekundach
}
klasa samochód :
C/C++
#ifndef SAMOCHOD_H
#define SAMOCHOD_H

#include <QObject>
#include<kolo.h>
class samochod
    : public QObject
{
    Q_OBJECT
    kolo * k;
public:
    explicit samochod( QObject * parent = nullptr );
public slots:
    void awariaKola();
};



#endif // SAMOCHOD_H
C/C++
#include "samochod.h"
#include<QDebug>
samochod::samochod( QObject * parent )
    : QObject( parent )
{
    k = new kolo; //tworzę obiekt koła
    //połączenie sygnału obiektu koła, ze slotem w klasie samochód
    connect( k, SIGNAL( awaria() ), this, SLOT( awariaKola() ) ); // to robi całą robotę. Połącz sygnał "awaria" obiektu "k" ze slotem "awariakola" obiektu klasy "samochod";
    // tu tkwi cały urok calbacków w stylu sygnał-slot z biblioteki Qt
    //bo w klasie koła piszesz "emit awaria" a funkcja klasy samochód wywoła się automatycznie!!!
}

void samochod::awariaKola()
{
    //gdy koło wyemituje awarję ten slot się wywoła się niejako automagicznie
    qDebug() << "koło zgłosiło awarję"; //wyplucie tekstu na konsole;
}
P-168745
mateczek
» 2018-01-15 04:55:06
Oczywiście mechanizm calbacków można również zaimplementować dość ładnie z wykorzystaniem biblioteki standardowej
std::function std::bind rejestrując w obiekcie tworzonym metodę rodzica.

Słowa kluczowe dla google "callback c++" np. ten wątek
https://stackoverflow.com​/questions/12338695​/c11-styled-callbacks
P-168746
setesh
Temat założony przez niniejszego użytkownika
» 2018-01-15 06:45:58
Dzięki. Wieczorem popatrze za tym :-)
P-168748
setesh
Temat założony przez niniejszego użytkownika
» 2018-01-16 21:53:24
Dziękuję za pomoc :-)

Rozwiązałem problem przenosząc część metod i zmiennych do osobnej klasy z której to dziedziczą inne. Dodatkowo metody te i zmienne są ustawione jako prywatne a dzięki zaprzyjaźnieniu innych klas nie są widoczne (oprócz konstruktorów) a nadal dostępne niezależnie jaki obiekt ma je wykorzystywać.

Jak udostępnie kod na githubie to wrzuce tu link aby inni mogli skorzystać :-)

Jeszcze raz dzięki za pomoc!
P-168789
« 1 »
  Strona 1 z 1