2015-01-22 11 views
15

W poniższym przykładzie dlaczego nazwa B::f() jest wywoływana, mimo że jest prywatna?Członek funkcji prywatnej o nazwie spoza klasy

Znam ten fakt: Dostęp jest sprawdzany w punkcie wywołania przy użyciu typu wyrażenia używanego do oznaczenia obiektu, dla którego wywołana jest funkcja składowa.

#include <iostream> 

class A { 
public: 
    virtual void f() { std::cout << "virtual_function"; } 
}; 

class B : public A { 
private: 
    void f() { std::cout << "private_function"; } 
}; 

void C(A &g) { g.f(); } 

int main() { 
    B b; 
    C(b); 
} 
+2

Bo to jest publiczne w A, przypuszczalnie z powodu faktu, że A jest rodzicem i używasz go z obiektu nie przeszkadza sprawdzenie zakresu na dziecko, to jest po prostu zastąpione przez fakt, że jest publiczna w A. Tylko moje myśli. – tom

+3

To, co powiedziałeś, wyjaśnia to - statyczny typ 'g' w' C' to 'A &', a 'f()' jest publiczną funkcją składową 'A'. Na tym właśnie polega kontrola dostępu. Zmień typ parametru "C()" na "B &", a Twój kod się nie skompiluje. – Praetorian

Odpowiedz

23

Ponieważ standard mówi tak:

[C++11: 11.5/1]: Zasady (pkt 11) dostępu do funkcji wirtualnego są określane przez jego oświadczenia i nie są objęte zasadami dla funkcji, która później nadpisuje je. [przykład:

class B { 
public: 
    virtual int f(); 
}; 
class D : public B { 
private: 
    int f(); 
}; 
void f() { 
    D d; 
    B* pb = &d; 
    D* pd = &d; 
    pb->f();  // OK: B::f() is public, 
       // D::f() is invoked 
    pd->f();  // error: D::f() is private 
} 

końcem przykład]

Przykładem jest takie same, lol.

4

Podczas czasie kompilacji kompilator C++ sprawdza dostępność funkcji i metod opartych na ich typ. W funkcji C zmienna g jest typu A (sprawdzana podczas kompilacji kodu), w której metoda f jest zadeklarowana jako publiczna.

Spójrz na this link

6

private funkcji może przesłonić public funkcji wirtualnych z klasy bazowej. Accessability jest, w rzeczywistości, całkowicie ignorowane przy ustalaniu, czy dana funkcja zastępuje inny, więc nawet w

// Redundant private for clarity: 
class A { private: virtual void foo(); }; 
class B : A { public: void foo(); }; 

B::foo zadajnikami A::foo.

+2

Ten przykład nie jest zbyt interesujący, biorąc pod uwagę, że 'B' deklaruje' foo' prywatne, tak jak 'A', _i_ dziedziczy ono prywatnie. –

+0

@LightnessRacesinOrbit Adjusted. – Columbo

+0

To wciąż ma prywatne dziedzictwo. Czy to jest celowe? Jeśli tak, to czy warto dodać również "private"? –

Powiązane problemy