using nieco inaczej

2008-07-14 18:42

W C++ istnieje słowo kluczowe using, z którym zetknął się chyba każdy. Zwykle dotyczy to nieśmiertelnej linijki:

  1. using namespace std;

Dlatego też słowo to kojarzy się przede wszystkim z przestrzeniami nazw (namespaces), a najczęściej tylko i wyłącznie z nimi.

Jednak using ma też swoje zastosowanie – i to zapewne znacznie ciekawsze – przy definiowaniu klas. Formalnie rzecz ujmując, słówko to pozwala wprowadzić składową pochodzącą z klasy bazowej (metodę lub pole) do zasięgu klasy pochodnej. Niezbyt to ekscytujące na pierwszy rzut oka, ale faktem jest, że dzięki skorzystaniu z using możemy dokonać przynajmniej jednej koniecznej czasami operacji. Możliwa jest mianowicie zmiana kontroli dostępu do danego składnika klasy, czyli określenie, czy ma on być prywatny czy może publiczny.
Wyobraźmy sobie na przykład, że w klasie bazowej mamy jakieś funkcje niepubliczne, które chcemy udostępnić na zewnątrz w klasie pochodnej:

  1. class Base { protected: void Fun(); };
  2.  
  3. class Foo : public Base
  4. {
  5.     public:
  6.         using Base::Fun; // teraz metoda Fun() jest publiczna
  7. };

Sytuacja nie jest wcale taka hipotetyczna. Sam miałem ostatnio taki przypadek, gdy najwygodniej było po prostu wbudować w klasę bazową pewną ukrytą funkcjonalność, która była używana przez wiele z jej klas pochodnych do ich wewnętrznych celów. Jednak niektóre z tych klas musiały tę “bazową” funkcjonalność udostępnić na zewnątrz jako publiczną. I tu przydało się użycie using w sposób zaprezentowany wyżej. (Dla zainteresowanych wspomnę, że opisywana sytuacja praktycznie wystąpiła u mnie w kodzie systemu GUI :]).

Tags: ,
Author: Xion, posted under Programming »


9 comments for post “using nieco inaczej”.
  1. Kwazar:
    July 14th, 2008 o 20:38

    Mi sie zawsze wydawalo, ze usign moze aby przywrocic dostep z klasy bazowej czyli w takiej sytuacji:

    1. class Base { public: void Fun(); };
    2.  
    3. class Foo : private Base
    4. {
    5.     public:
    6.         using Base::Fun; // teraz metoda Fun() jest publiczna
    7. };

    Jeżeli sie myle to mnie poprawcie :P

  2. Gynvael:
    July 14th, 2008 o 20:43

    Ooo ciekawe ;>
    Dobrze wiedzieć ;>

  3. Xion:
    July 14th, 2008 o 20:52

    Kwazar: Jak najbardziej tak. To co opisałem, to tylko jedno z “pozanamespace’owych” zastosowań using. Ty podałeś drugie (w gruncie rzeczy dość podobne do pierwszego, bo w Foo metoda Fun() jest prywatna i też używasz using do jej upubliczenia). Trzecim zastosowaniem jest przeciążenie metody odziedziczonej w klasie pochodnej zamiast jej ukrywania. Czwarte pojawi się w C++0x i będzie polegało na możliwości “dziedziczenia” (albo raczej automatycznego generowania) konstruktorów.

    Być może istnieją też i inne przypadki podobnego użycia using, ale jak dotąd o nich nie słyszałem :) (Co aczkolwiek nie jest żadnym argumentem za tym, że ich nie ma :>).

  4. Luq:
    July 14th, 2008 o 21:12

    akurat takiego czegoś kiedyś potrzebowałem i zastanawiałem się czy to jest możliwe thx:)

  5. krajek:
    July 14th, 2008 o 21:15

    Nie no czy kiedyś skończą Ci się sztuczki z rękawa?:D

  6. shoter:
    July 15th, 2008 o 16:15

    Kwazar też mi się to wydawało podejrzane :),sprwadziłem metodą Xiona i działało! :)

  7. Kwazar:
    July 16th, 2008 o 11:05

    Czyli w ten sposob mozna np w jakiejs klasie engina graficznego dostac sie do wszystkich skladnikow prywatnych :D

  8. Xion:
    July 16th, 2008 o 11:57

    Nie można. Składniki prywatne nie są dziedziczone, więc zrobienie klasy pochodnej dziedziczącej po klasie “z engine’u” nic nie da.

  9. Kwazar:
    July 16th, 2008 o 12:14

    Fakt sprawdzilem teraz w visualu i rzeczywiscie nie da rady.

Comments are disabled.
 


© 2019 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.