2013-02-27 7 views
6

akapit poniżej ekstrahowano od strony 420 od Stroustup książce „C++ Programming Language” (wydanie trzecie):Myślę, że poniższe stwierdzenie jest nieprawidłowe lub czegoś brakuje?

Ponieważ wskaźnik do członka wirtualnego (s w tym przykładzie) jest rodzajem offset, nie zależy od lokalizacji obiektu w pamięci. Wskaźnik do wirtualnego elementu można zatem bezpiecznie przepuścić między różnymi przestrzeniami adresowymi, o ile ten sam układ obiektów jest używany w obu wersjach. Podobnie jak wskaźniki do zwykłych funkcji, wskaźniki do niewirtualnych funkcji składowych nie mogą być wymieniane między przestrzeniami adresowymi.

Sporuję ostatnie zdanie w tym akapicie. Poniżej znajduje się fragment kodu, w którym wskaźniki bez funkcji bez funkcji, foo() i foo1() są wymieniane między jednym obiektem bazowym a i obiektem pochodnym b, bez problemu.

Czego nie można zrobić, to przeciążenie dowolnej z funkcji bazy, foo() lub foo1(), w klasie pochodnej, ponieważ w tym przypadku kompilator wyśle ​​błąd, jak pokazano poniżej.

#include <iostream> 

class A 
{ 
    int i; 
    public: 
    A() : i(1) {} 
    void foo() { std::cout << i << '\n'; } 
    void foo1() { std::cout << 2 * i << '\n'; } 
}; 

class B: public A 
{ 
    int j; 
    public: 
    B() : A(), j(2) {} 
// void foo() { std::cout << j << '\n'; } 
}; 

int main() 
{ 
    typedef void (A::* PMF)(); 
    PMF p = &B::foo; // error C2374: 'p' redefinition, multiple initialization 
         // if foo() is overloaded in B. 
    PMF q = &B::foo1; 
    B b; 
    (b.*p)(); 
    (b.*q)(); 

    A a; 
    (a.*p)(); 
    (a.*q)(); 
} 
+6

Moje czytanie "wymiany między przestrzeniami adresowymi" było czymś w rodzaju bezpośredniej transmisji wskaźnika do * innego procesu * w systemie operacyjnym. – ulidtko

Odpowiedz

1

To zdanie jest poprawne: W (standard) C++, program lub raczej proces ma dokładnie jedną przestrzeń adresową. Jak więc ulidtko wskazał, to zdanie odnosi się do możliwości wymiany wskaźników na wirtualne i nie-wirtualne funkcje składowe między przestrzeniami adresowymi różnych procesów.

non-virtual funkcja członek klasy jest dość dużo standard funkcja z niejawny argument do obiektu, który nazywamy go (na to wskaźnika). W związku z tym podczas ładowania zostanie mu przypisany pewien adres w przestrzeni adresowej twojego procesu. Gdzie dokładnie kończy się w twojej przestrzeni adresowej, zależy oczywiście od twojej platformy i czy ta funkcja członka jest częścią dynamicznie połączonej biblioteki. Chodzi o to, że w przypadku dwóch procesów niekoniecznie musi to być ten sam adres. Przekazywanie wskaźnika i wykonywanie takiej funkcji w innym procesie może potencjalnie "podpalić twoją maszynę".

wirtualny członek funkcja jest wciąż niemal tak samo jak funkcja użytkownik nie wirtualnym, jak w „pewnym adresem w pamięci przejść do na wykonanie i przekazać swoją ten wskaźnik”, ale jest wywoływana poprzez wirtualna tablica funkcji (vtable) zamiast bezpośrednio. Zatem wskaźnik do funkcji wirtualnego elementu jest właściwie tylko indeksem do tabeli funkcji wirtualnego obiektu. Wywołanie tej funkcji wykonuje wtedy coś w stylu "pobranie wskaźnika obiektu, może zwiększyć wskaźnik, aby dostać się do tabeli vtable obiektu i przeskoczyć do adresu pod danym indeksem tej tabeli, przekazując adres samego obiektu jako wskaźnik ". Tak więc to pośrednie poprzez vtable powoduje wymianę wskaźnika na funkcję wirtualnego elementu między przestrzeniami adresowymi.

Nota prawna: Pochylam się trochę nad moim "Naprawdę wiem o czym mówię" - strefa komfortu tutaj. Więc na wypadek, gdy przesadzam sobie z czymś lub co gorsza, ale zaangażowałem się w dystrybucję fałszywych informacji, nie krępuj się rozdzielić odpowiedzi;).

0

Wskaźnik zawsze będzie istnieć jako pamięć wirtualną więc prawdą jest, można sprawdzić adres i będzie zobaczyć nie ma fizycznego wskaźnik do adresu pamięci

Ponieważ wskaźnik do wirtualnego członka (s w tym przykładzie) jest rodzajem przesunięcia, nie zależy od położenia obiektu w pamięci. Wskaźnik do wirtualnego elementu można zatem bezpiecznie przenosić między różnymi przestrzeniami adresowymi, o ile ten sam układ obiektów jest używany w obu. Podobnie jak wskaźniki do zwykłych funkcji, wskaźniki do niewirtualnych funkcji członkowskich nie mogą być wymieniane między przestrzeniami adresowymi.

Powiązane problemy