Skocz do zawartości

Jak zrobić wskaznik globalny na wywołanie metody z klasy?


Pomocna odpowiedź

Napisano

Witam

jak w tym przykładzie zrobić wskaźnik globalny, ktorym będe mógł wywołać w funkcji mojeAuto metode z klasy?




void mojeAuto(){

 // wsk->wyswietl();
}


class Marka {
public:
  virtual void wyswietl() = 0; // czysta funkcja wirtualna
  
};

class Hyundai : public Marka {
  String marka;
  String model;
  int rok;

public:
  Hyundai(String marka="Hyundai", String model="Tucson", int rok=2021) {
    this->marka = marka;
    this->model = model;
    this->rok = rok;
  }
  virtual void wyswietl() {  

    printf("Marka Samochodu %s\n", marka);
    printf("Model Samochodu %s\n", model);
    printf("Rok Samochodu %d\n\n", rok);
  }
}; Hyundai h;
////////////////////////////////////////

class Kia : public Marka {
  String marka;
  String model;
  int rok;

public:
   Kia(String marka="Hyundai", String model="Tucson", int rok=2021) {
    this->marka = marka;
    this->model = model;
    this->rok = rok;
  }
  virtual void wyswietl() {
    printf("Marka Samochodu %s\n", marka);
    printf("Model Samochodu %s\n", model);
    printf("Rok Samochodu %d\n", rok);
 
  }
}; Kia k; 




void setup() {
  Serial.begin(115200);
}
void loop() {

  if( jakis warunek ) {

    Marka *wsk;
    wsk = &h;
    wsk -> wyswietl();
    wsk = &k;
    wsk -> wyswietl();
   }
  
}

 

(edytowany)

@nebraska, nie wnikam czemu tak, ale chodzi ci o to?

 
class Marka {
public:
	virtual void wyswietl() = 0; // czysta funkcja wirtualna
} * wsk_globalny; // tworzy wskaźnik globalny

class Hyundai : public Marka {
	String marka, model;
	int rok;

public:
	Hyundai(String marka="Hyundai", String model="Tucson", int rok=2021) {
		this->marka = marka;
		this->model = model;
		this->rok = rok;
	}

	virtual void wyswietl() {
		printf("[SAMOCHÓD]\nMarka: %s\nModel: %s\nRok: %d\n\n", marka, model, rok);
	}
	
} h; // obiekt globalny

////////////////////////////////////////

class Kia : public Marka {
	String marka, model;
	int rok;

public:
	Kia(String marka="Kia", String model="Yakotako", int rok=1999) {
		this->marka = marka;
		this->model = model;
		this->rok = rok;
	}

	virtual void wyswietl() {
		printf("[SAMOCHÓD]\nMarka: %s\nModel: %s\nRok: %d\n\n", marka, model, rok);
	}

} k; // obiekt globalny

// pierwsza wersja funkcji, bez argumentu
void mojeAuto(){
	printf(">> Funkcja \"mojeAuto()\", WERSJA BEZ ARGUMENTU <<\n");
	wsk_globalny ->wyswietl();
}

// druga wersja funkcji, z argumentem
void mojeAuto(Marka * x){
	wsk_globalny = x;
	printf(">> Funkcja \"mojeAuto()\", WERSJA Z ARGUMENTEM <<\n");
	wsk_globalny ->wyswietl();
}

void setup() {
	Serial.begin(115200);
}

void loop() {

	if(true) {
		Marka *wsk; // wskaźnik lokalny pokazujący później na obiekty globalne
		wsk = &h;
		wsk -> wyswietl();
		wsk = &k;
		wsk -> wyswietl();
		
		wsk_globalny = &h; // wskaźnik globalny, obiekt globalny
		mojeAuto();
		wsk_globalny = &k;
		mojeAuto();

		// ewentualnie druga wersja funkcji mojeAuto(); argumentem jest adres obiektu globalnego
		mojeAuto(&h);
		mojeAuto(&k);

		printf("=====================\n");
	}
	
	delay(2000);
}

 

Edytowano przez orb777
  • Lubię! 1
2 godziny temu, orb777 napisał:

@nebraska, nie wnikam czemu tak, ale chodzi ci o to?

  Ukryj treść
class Marka {
public:
	virtual void wyswietl() = 0; // czysta funkcja wirtualna
} * wsk_globalny; // tworzy wskaźnik globalny

class Hyundai : public Marka {
	String marka, model;
	int rok;

public:
	Hyundai(String marka="Hyundai", String model="Tucson", int rok=2021) {
		this->marka = marka;
		this->model = model;
		this->rok = rok;
	}

	virtual void wyswietl() {
		printf("[SAMOCHÓD]\nMarka: %s\nModel: %s\nRok: %d\n\n", marka, model, rok);
	}
	
} h; // obiekt globalny

////////////////////////////////////////

class Kia : public Marka {
	String marka, model;
	int rok;

public:
	Kia(String marka="Kia", String model="Yakotako", int rok=1999) {
		this->marka = marka;
		this->model = model;
		this->rok = rok;
	}

	virtual void wyswietl() {
		printf("[SAMOCHÓD]\nMarka: %s\nModel: %s\nRok: %d\n\n", marka, model, rok);
	}

} k; // obiekt globalny

// pierwsza wersja funkcji, bez argumentu
void mojeAuto(){
	printf(">> Funkcja \"mojeAuto()\", WERSJA BEZ ARGUMENTU <<\n");
	wsk_globalny ->wyswietl();
}

// druga wersja funkcji, z argumentem
void mojeAuto(Marka * x){
	wsk_globalny = x;
	printf(">> Funkcja \"mojeAuto()\", WERSJA Z ARGUMENTEM <<\n");
	wsk_globalny ->wyswietl();
}

void setup() {
	Serial.begin(115200);
}

void loop() {

	if(true) {
		Marka *wsk; // wskaźnik lokalny pokazujący później na obiekty globalne
		wsk = &h;
		wsk -> wyswietl();
		wsk = &k;
		wsk -> wyswietl();
		
		wsk_globalny = &h; // wskaźnik globalny, obiekt globalny
		mojeAuto();
		wsk_globalny = &k;
		mojeAuto();

		// ewentualnie druga wersja funkcji mojeAuto(); argumentem jest adres obiektu globalnego
		mojeAuto(&h);
		mojeAuto(&k);

		printf("=====================\n");
	}
	
	delay(2000);
}

 

Chyba nie o to mi chodziło. Źle to przedstawiłem.

Załóżmy że mam dwie klasy(w rzeczywistosci ich mam 15) i w drugiej klasie mam metode tez wirtualna "wyposazenie", którą chce przenieść do pierwszej klasy do metody "wyswietl" . Czyli w metodzie pierwszej klasy "wyswietl" chce wykonać metode wyposazenie która jest w drugiej klasie.


class Marka {
public:
  virtual void wyswietl() = 0;     // czysta funkcja wirtualna
  virtual void wyposazenie() = 0; // czysta funkcja wirtualna
  
};

class Hyundai : public Marka {
  String marka;
  String model;
  int rok;

public:
  Hyundai(String marka="Hyundai", String model="Tucson", int rok=2021) {
    this->marka = marka;
    this->model = model;
    this->rok = rok;
  }
  virtual void wyswietl() {  

    printf("Marka Samochodu %s\n", marka);
    printf("Model Samochodu %s\n", model);
    printf("Rok Samochodu %d\n\n", rok);

    // tutaj chce wykonac metode wyposazenie //////////////////////////////////////////////////////
  }
}; Hyundai h;
////////////////////////////////////////

class Kia : public Marka {
  String marka;
  String model;
  int rok;

public:
   Kia(String marka="Hyundai", String model="Tucson", int rok=2021) {
    this->marka = marka;
    this->model = model;
    this->rok = rok;
  }
  virtual void wyswietl() {
    printf("Marka Samochodu %s\n", marka);
    printf("Model Samochodu %s\n", model);
    printf("Rok Samochodu %d\n", rok);
 
  }
    virtual void wyposazenie() {
    printf("Wersja %s\n", marka);
  }

}; Kia k; 




void setup() {
  Serial.begin(115200);
}
void loop() {

  
}

 

W takim razie będziesz musiał zdefiniować metodę "wyposazenie()" w klasie pochodnej "hyundai" i wywołać ją w metodzie wyświetl() tej klasy, skoro zadeklarowałeś obie jako czysto wirtualne. Inaczej kompilator wywali pewnie błąd.

Powiedzmy, że chciałeś mieć pewną "swobodę" w klasach pochodnych deklarując w klasie podstawowej "marka" obie metody jako czysto wirtualne, ale i tak musisz je zdefiniować dla obu klas pochodnych. Hyundai nie "zarazi się w magiczny sposób" definicją metody "wyposazenie()" od kia. Chyba, że piszę coś źle, bo nie do końca rozumuję twoje rozumowanie.

(edytowany)

Tak, w pierwszej klasie tez mam dodaną tylko po to zeby kompilator nie wywalał błędu ciało metody jest puste.

Wszystko mi działa dobrze. Mam 15 klas i między nimi mam potrzebne podstawienia danej metody problem w tym ze jesli dam nad klasą to mam "komunikat nie zadeklarowany ponieważ jej nie widzi. 

Zastanawiam się jak to ugryźć. Na pewno istniejej jakiś mechanizm co taką funkcjonalność pozwoli uzyskać.


class Marka {
public:
  virtual void wyswietl() = 0;     // czysta funkcja wirtualna
  virtual void wyposazenie() = 0;     // czysta funkcja wirtualna
};
Marka *wsk;



class Hyundai : public Marka {
  String marka;
  String model;
  int rok;

public:
  Hyundai(String marka="Hyundai", String model="Tucson", int rok=2021) {
    this->marka = marka;
    this->model = model;
    this->rok = rok;
  }
  virtual void wyswietl() {  

    printf("Marka Samochodu %s\n", marka);
    printf("Model Samochodu %s\n", model);
    printf("Rok Samochodu %d\n\n", rok);
  }  
  virtual void wyposazenie(){}

}; Hyundai h;
////////////////////////////////////////

class Kia : public Marka {
  String marka;
  String model;
  int rok;

public:
   Kia(String marka="Hyundai", String model="Tucson", int rok=2021) {
    this->marka = marka;
    this->model = model;
    this->rok = rok;
  }
  virtual void wyswietl() {
    printf("Marka Samochodu %s\n", marka);
    printf("Model Samochodu %s\n", model);
    printf("Rok Samochodu %d\n", rok);
  }
   virtual void wyposazenie() {
     printf("Wyposazenie \n");
   }

}; Kia k;  



void setup() {
  Serial.begin(115200);
}
void loop() {



  delay(3000);
}

 

Edytowano przez nebraska

@nebraska Napisz proszę, jaki efekt i po co chcesz osiągnąć. Na podstawie Twojego przykładu zupełnie nie rozumiem czym te klasy się od siebie różnią. Oczywiście poza nazwą. Piszesz: <<problem w tym ze jeśli dam nad klasą to mam "komunikat nie zadeklarowany ponieważ jej nie widzi.  >> Co rozumiesz przez "dam nad klasą"? Co nie widzi, kogo i skąd?

Przepraszam, ale się nie domyślam. Pokaż proszę w którym miejscu w kodzie chcesz użyć wywołania jakiej funkcji, i dlaczego. Użycie klasy wirtualnej ma zapewne uzasadnienie, ale z Twojego kodu (rozumiem że to przykładowy fragment) ono raczej nie wynika, bo funkcje wirtualne w obu klasach wyglądają identycznie.

Gdybym miał odnieść się bezpośrednio do Twojego pytania w temacie, to powiedział bym "deklarujesz wskaźnik do funkcji, nadjesz mu wartość i używasz jak funkcję" ale zapewne nie o to Ci chodzi.

(edytowany)
13 godzin temu, bjrk napisał:

@nebraska Napisz proszę, jaki efekt i po co chcesz osiągnąć. Na podstawie Twojego przykładu zupełnie nie rozumiem czym te klasy się od siebie różnią. Oczywiście poza nazwą.

Mój program posiada około 3tys linii robi różne rzeczy, podałem przykład dwóch klas z jakimś tam wymyślnym przykładem, ponieważ nikt nie będzie analizował kodu który ma 3000 linii żeby zrozumieć zasadę działania całego programu.

13 godzin temu, bjrk napisał:

Piszesz: <<problem w tym ze jeśli dam nad klasą to mam "komunikat nie zadeklarowany ponieważ jej nie widzi.  >> Co rozumiesz przez "dam nad klasą"? Co nie widzi, kogo i skąd?

Ok, dla lepszego zrozumienia odwróćmy sytuacje. W poniższym przykładzie chce wykonać metode wyposażenie();  z klasy Hyundai w klasie Kia w metodzie wyswietl(); . W klasie Kia w metodzie wyswietl();  z użyciem wskaźnika poliformicznego wykonuje sobie bez problemu metode wyposażenie z klasy Hyundai.


class Marka {
public:
  virtual void wyswietl() = 0;         // czysta funkcja wirtualna
  virtual void wyposazenie() = 0;     // czysta funkcja wirtualna
};
Marka *wsk;


class Hyundai : public Marka {
  String marka;
  String model;
  int rok;

public:
  Hyundai(String marka="Hyundai", String model="Tucson", int rok=2021) {
    this->marka = marka;
    this->model = model;
    this->rok = rok;
  }
  virtual void wyswietl() {  

    printf("Marka Samochodu %s\n", marka);
    printf("Model Samochodu %s\n", model);
    printf("Rok Samochodu %d\n\n", rok);
  }  
  virtual void wyposazenie(){
      
    printf("Wyposazenie \n"); // ----->>>>>> metoda ktora przenosze do klasy Kia w metode wyswietl();
  }

}; Hyundai h;
////////////////////////////////////////

class Kia : public Marka {
  String marka;
  String model;
  int rok;

public:
   Kia(String marka="Kia", String model="Sportage", int rok=2023) {
    this->marka = marka;
    this->model = model;
    this->rok = rok;
  }
  virtual void wyswietl() {
    printf("Marka Samochodu %s\n", marka);
    printf("Model Samochodu %s\n", model);
    printf("Rok Samochodu %d\n", rok);

    wsk = &h;
    wsk->wyposazenie(); // tutaj wykonuje metode z klasy powyzej w metodzie wyswietl ---------------------------------------------


  }
   virtual void wyposazenie() {}
   

}; Kia k;  



void setup() {
  Serial.begin(115200);
}
void loop() {
  if (Serial.available() > 0) {
    String message = Serial.readStringUntil('\n');

    if (message == "a") { 

    wsk = &h;
    wsk -> wyswietl();
    }
    if (message == "b") {  
    wsk = &k;
    wsk -> wyswietl();


    }
  }
}

 

Wracam do sytuacji jak na początku. Obiekt k na który wskazuje adres wskaznika wsk bedzie jako nie zadeklarowany wsk = &k; , ponieważ jest jest nad klasą Kia. Mam nadzieję że teraz wiesz o co mi chodzi.

Np z 15 klasy bedę chciał coś przenieść do pierwszej klasy do danej metody przysłaniając funkcje wirualną w klasie bazowej, zeby mogło się wykonać.

 


class Marka {
public:
  virtual void wyswietl() = 0;         // czysta funkcja wirtualna
  virtual void wyposazenie() = 0;     // czysta funkcja wirtualna
};
Marka *wsk;


class Hyundai : public Marka {
  String marka;
  String model;
  int rok;

public:
  Hyundai(String marka="Hyundai", String model="Tucson", int rok=2021) {
    this->marka = marka;
    this->model = model;
    this->rok = rok;
  }
  virtual void wyswietl() {  

    printf("Marka Samochodu %s\n", marka);
    printf("Model Samochodu %s\n", model);
    printf("Rok Samochodu %d\n\n", rok);

    wsk = &k;
    wsk->wyposazenie(); // tutaj wykonuje metode z klasy ponizej w metodzie wyswietl ---------------------------------------------
  }  
  virtual void wyposazenie(){}

}; Hyundai h;
////////////////////////////////////////

class Kia : public Marka {
  String marka;
  String model;
  int rok;

public:
   Kia(String marka="Kia", String model="Sportage", int rok=2023) {
    this->marka = marka;
    this->model = model;
    this->rok = rok;
  }
  virtual void wyswietl() {
    printf("Marka Samochodu %s\n", marka);
    printf("Model Samochodu %s\n", model);
    printf("Rok Samochodu %d\n", rok);

  }
   virtual void wyposazenie() {
    printf("Wyposazenie \n"); // ----->>>>>> metoda ktora przenosze do klasy Hyundai w metode wyswietl();
   }
   

}; Kia k;  



void setup() {
  Serial.begin(115200);
}
void loop() {
  if (Serial.available() > 0) {
    String message = Serial.readStringUntil('\n');

    if (message == "a") { 

    wsk = &h;
    wsk -> wyswietl();
    }
    if (message == "b") {  
    wsk = &k;
    wsk -> wyswietl();


    }
  }
}

 

Edytowano przez nebraska
48 minut temu, etet100 napisał:

Robisz coś bardzo źle. To nie ma najmniejszego sensu. 

chętnie się naucze czegoś nowego jak wybrnąć z tego. Moze jakiś pomysł?

 

53 minuty temu, ethanak napisał:

@nebraska ja tu widzę wywołanie metody obiektu a nie klasy, ale ja się nie znam...

bardziej miałem na myśli wywołanie metody z klasy do innej klasy😜

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...