• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wskaźnik na metodę zapis C++

VPS Starter Arubacloud
+1 głos
234 wizyt
pytanie zadane 8 maja 2021 w C i C++ przez profesorek96 Szeryf (91,420 p.)

Witam,

Ostatnio bawiłem się wskaźnikami na metody w klasie. Stworzyłem tablicę zawierającą wskaźniki do czterech metod. Finalnie z zewnątrz udało mi się wywołać każdą z metod dla obiektu tej klasy, jednak sposób w jaki tego dokonałem jest dość dziwny. Czy nie dało by się tego jakoś ładniej wykonać bez użycia aż tylko * ?

Plik nagłówkowy.

#pragma once
class moja_klasa;
typedef double (moja_klasa::*wf)();
class moja_klasa
{
    public:
    double a,b;
    wf tab[4];
    moja_klasa(double a,double b);
    double f1();
    double f2();
    double f3();
    double f4();
};

Plik źródłowy

#include "moja_klasa.h"
moja_klasa::moja_klasa(double a,double b)
{
    this->a=a;
    this->b=b;
    tab[0]=&moja_klasa::f1;
    tab[1]=&moja_klasa::f2;
    tab[2]=&moja_klasa::f3;
    tab[3]=&moja_klasa::f4;
}
double moja_klasa::f1()
{
    return a+b;
}
double moja_klasa::f2()
{
    return a-b;
}
double moja_klasa::f3()
{
    return a*b;
}
double moja_klasa::f4()
{
    return a/b;
}

funkcja główna:

#include <iostream>
#include "moja_klasa.h"
using namespace std;
int main()
{
    moja_klasa moja(3,9);
    for(int i=0;i<4;i++)
    {
        cout<<(moja.**(moja.tab+i))()<<endl;
    }
    cout<<moja.f1();
    return 0;
}

Moje pytanie dotyczy tej linii:

cout<<(moja.**(moja.tab+i))()<<endl;

 

1
komentarz 8 maja 2021 przez tkz Nałogowiec (42,000 p.)

https://isocpp.org/wiki/faq/pointers-to-members#dotstar-vs-arrowstar

W tej postaci raczej tego nie uprościsz, mógłbyś wyrzucić tablice z samej klasy. 

// Example program
#include <iostream>
#include <string>

class moja_klasa
{
    public:
    double a,b;
    moja_klasa(double a,double b);
    double f1();
    double f2();
    double f3();
    double f4();
};

moja_klasa::moja_klasa(double a,double b)
{
    this->a=a;
    this->b=b;

}
double moja_klasa::f1()
{
    return a+b;
}
double moja_klasa::f2()
{
    return a-b;
}
double moja_klasa::f3()
{
    return a*b;
}
double moja_klasa::f4()
{
    return a/b;
}

#include <iostream>
using namespace std;
int main()
{
    moja_klasa moja(3,9);
    double (moja_klasa::*tab_wsk_fun[4])()= { &moja_klasa::f1, &moja_klasa::f2,&moja_klasa::f3,&moja_klasa::f4};
    moja_klasa c1(3,5);
    for(int i=0;i<4;i++)
    {
        cout<<(moja.*tab_wsk_fun[i])()<<endl;
    }
    return 0;
}

Zostaje jeszcze auto i std::function. Możliwości pewnie jest sporo. 

komentarz 8 maja 2021 przez Witut Początkujący (310 p.)

@profesorek96, mógłbyś mi wytłumaczyć co oznaczają te fragmenty kodu? Bo nie za bardzo rozumiem :((

PLIK NAGŁÓWKOWY:

typedef double (moja_klasa::*wf)();

FUNKCJA GŁÓWNA:

cout<<(moja.**(moja.tab+i))()<<endl;

Jeśli chodzi o ten przypadek to nie rozumiem jak mają działać te dwa operatory wyłuskania obok siebie.Nie spotkałem się wcześniej z takim zapisem

 

 

komentarz 8 maja 2021 przez tkz Nałogowiec (42,000 p.)
https://cpp0x.pl/kursy/Kurs-C++/Poziom-X/Wskaznik-na-funkcje/249 - pierwsze pytanie

A drugie pytanie zostało wyjaśnione w odpowiedzi.
komentarz 8 maja 2021 przez Witut Początkujący (310 p.)
Wielkie dzięki :))
komentarz 8 maja 2021 przez profesorek96 Szeryf (91,420 p.)
@Witut

Operator gwiazdki postawiony przed zmienna wskaźnikową powoduje wyłuskanie wartości, pokazuje wartość jaka jest pod danym adresem. Dwa operatory gwiazdki to nic innego jak podwójne wyłuskanie. W języku C++ jak i C większe programy dzieli się na kilka plików, kompiluje się każdy plik z osobna, następnie linker łączy te składowe kompilacji w jeden plik wykonywalny. Polecam zapoznać się z teorią kompilacji.

https://cpp-polska.pl/post/wstep-do-teorii-kompilacji

1 odpowiedź

+3 głosów
odpowiedź 8 maja 2021 przez adrian17 Ekspert (344,100 p.)
wybrane 8 maja 2021 przez profesorek96
 
Najlepsza
*(moja.tab+i)

To jest zwykłe indeksowanie tablicy, więc można zastąpić przez:

cout<<(moja.*(moja.tab[i]))()<<endl;

 

Podobne pytania

0 głosów
2 odpowiedzi 492 wizyt
pytanie zadane 27 grudnia 2019 w C i C++ przez Sejdi Początkujący (460 p.)
0 głosów
2 odpowiedzi 1,242 wizyt
0 głosów
1 odpowiedź 205 wizyt

92,452 zapytań

141,262 odpowiedzi

319,077 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...