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

pytanie c++:) (polimorfizm)

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
+2 głosów
547 wizyt
pytanie zadane 4 kwietnia 2015 w C i C++ przez achilles147 Dyskutant (9,580 p.)
edycja 4 kwietnia 2015 przez achilles147

Witam postanowiłem zapytać o coś czego nie do końca rozumiem. Otóż mam problem dotyczący pewnego zagadnienia związanego z jak mniemam działania funkcji wirtualnych w c++. Problem dobrze przedstawi pewien kawałek kodu. Otóż mamy taką sytuację, w wyniku której na konsoli ukazuje się nam liczba 16. I teraz poblem mój tkwi w tym dlaczego akurat 16. Wiadomo mamy wskaźnik klasy bazowej, który wskazuję na obiekt klasy pochodnej. Wywoływana jest funkcja shift, a jako że jest ona funkcją wirtualną w klasie bazowej zostanie wywołana jej definicja z klasy pochodnej, która zwraca nam parametr n przesunięty bitowo o 3 miejsca. W wypadku nie podania parametru jest ustawiony parametr domyślny n=3. Jeżeli wykonamy na nim operacje przesunięcia bitowego o 3 miejsca w lewo to mamy następująco : 00000011->00011000 co daje nam liczbę 24 (zły wynik). Oczywiście wynik byłby poprawny dla parametru n=2, który jest podany jako domyślny parametr n w definicji funkcji shift klasy  bazowej. Nie dokońca rozumiem dlaczego parametr domyślny miałby być ustawiony w definicji klasy bazowej a wywołana została funkcja klasy pochodnej.

 

#include "stdafx.h"
#include <iostream>
using namespace std;
class B
{
public:
    virtual int shift(int n = 2) const { return n << 2; }
};
class D
    : public B
{
public:
    int shift(int n = 3) const { return n << 3; }
};
int _tmain(int argc, _TCHAR* argv[])
{
    const D d;
    const B *b = &d;
    std::cout << b->shift() << std::endl;
	system("PAUSE");
	return 0;
}

 

3 odpowiedzi

0 głosów
odpowiedź 4 kwietnia 2015 przez killerman Użytkownik (660 p.)
Polimorfizm nie zadziała bo masz inne sygnatury funkcji...
komentarz 4 kwietnia 2015 przez achilles147 Dyskutant (9,580 p.)
czyli jeżeli funkcje różnią się domyślnym parametrem to polimorfizm nie zadziała?
0 głosów
odpowiedź 4 kwietnia 2015 przez achilles147 Dyskutant (9,580 p.)
ale jeżeli polimorfizm nie zadziała to rozumiem, że zostanie wywołana funkcja z klasy bazowej. Czyli n=2  return n<<2;

00000010->00001000 czyli wynik równy 8 a nie 16...
komentarz 4 kwietnia 2015 przez Jimmy Początkujący (450 p.)
Zauważ że jeżeli zmienisz ciało twojej funkcji wirtualnej z klasy bazowej to i tak to nic nie zmieni ponieważ zostaje ona przysłonięta przez funkcje z klasy pochodnej w której n przesuwasz o 3 miejsca.
komentarz 4 kwietnia 2015 przez killerman Użytkownik (660 p.)

Co do złego przesunięcia to usuń const ze swojej metody

komentarz 4 kwietnia 2015 przez achilles147 Dyskutant (9,580 p.)

tak wiem wiem przesunie się o 3 miejsca ale dlaczego n=2? a nie n=3

int shift(int n = 3) const { return n << 3; }

komentarz 4 kwietnia 2015 przez killerman Użytkownik (660 p.)

const dodane w twoich metodach oznacza, że funkcja nie będzie zmieniać żadnej wartości a zmienia bo wykorzystuje przesuniecie bitowe dla zmiennej n. Przez to tworzy się coś dziwnego czego nie rozumiem, twój program przyjmuje wartość n dla metody z klasy C a wykonuje ciało funkcji z klasy D. Nie mam pojęcia czemu się tak dzieje ale usunięcie const naprawi problem.

komentarz 4 kwietnia 2015 przez achilles147 Dyskutant (9,580 p.)
edycja 4 kwietnia 2015 przez achilles147
const nie oznacza czasem że funkcja nie będzie zmieniać żadnych składowych klasy?

n nie jest składową a tylko lokalną zmienną.
0 głosów
odpowiedź 4 kwietnia 2015 przez achilles147 Dyskutant (9,580 p.)
dla ułatwienia zrozumienia mojego problemu zedytowałem klasy, żeby pokazywały co się w ogóle wywołuje. Jak widać wywołuje się D::shift(2).

class B
{
public:
    virtual int shift(int n = 2) const {
        cout<<"B::Shift("<<n<<")"<<endl;
        return n << 2; }
};
class D
    : public B
{
public:
    int shift(int n = 3) const
    {
        cout<<"D::Shift("<<n<<")"<<endl;
        return n << 3;
    }
};
komentarz 5 kwietnia 2015 przez killerman Użytkownik (660 p.)

w polimorfizmie nie uzywa się argumentów domniemanych bo będą one pobierane z klasy bazowej. Tak działa kompilator.

 

   A virtual function call (10.3) uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. An overriding function in a derived class does not acquire default arguments from the function it overrides.

Podobne pytania

0 głosów
1 odpowiedź 579 wizyt
pytanie zadane 16 października 2018 w Java przez Kubs Mądrala (5,190 p.)
0 głosów
1 odpowiedź 693 wizyt
pytanie zadane 25 czerwca 2018 w C i C++ przez niezalogowany
0 głosów
1 odpowiedź 181 wizyt
pytanie zadane 8 czerwca 2018 w C i C++ przez Fretkamaciejek Nowicjusz (190 p.)

93,103 zapytań

142,077 odpowiedzi

321,567 komentarzy

62,445 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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...