2011-07-06 13 views

Odpowiedz

14

Mechanizm wywołań wirtualnych (zwykle v-table, ale nie musi być) jest konfigurowany podczas inicjator ctor, po skonstruowaniu bazowych podobiektów i przed budową prętów. Sekcja [class.base.init] dekretów:

Funkcje członkowskie (w tym funkcje wirtualnego członka, 10.3) można wywoływać dla obiektu w trakcie budowy. Podobnie obiekt będący w budowie może być operandem operatora typeid (5.2.8) lub dynamic_cast (5.2.7). Jeśli jednak te operacje są wykonywane w inicjatorze inicjującym(lub w funkcji zwanej bezpośrednio lub pośrednio z inicjatora ctor ) przed wykonaniem wszystkich inicjatorów pamięci dla klas bazowych, wynik operacji jest niezdefiniowany.

W rzeczywistości podczas budowy podstawowych obiektów podrzędnych istnieje wirtualna maszyna funkcyjna, ale jest ona ustawiana dla klasy bazowej. Sekcja [class.cdtor] mówi:

Funkcje członkowskie, w tym funkcje wirtualne (10.3), mogą być wywoływane podczas budowy lub niszczenia (12.6.2). Gdy funkcja wirtualna jest wywoływana bezpośrednio lub pośrednio z konstruktora lub destruktora, w tym podczas konstruowania lub niszczenia niestatycznych elementów danych klasy, a obiektem, do którego odnosi się wywołanie, jest obiekt (wywołanie go x) w trakcie budowy lub zniszczenie, funkcja nazywa się ostatecznym nadpisaniem klasy w klasie konstruktora lub destruktora, a nie nadpisuje ją w klasie pochodnej. Jeśli wywołanie funkcji wirtualnej korzysta z jawnego dostępu do elementu klasy (5.2.5), a wyrażenie obiektowe odnosi się do całego obiektu x lub jednego z podobiektów klasy bazowej tego obiektu, ale nie do obiektu x lub jednego z jego podobiektów klasy podstawowej, zachowanie jest niezdefiniowane .

+0

Doe s oznacza to, że 'vptr' będzie modyfikowane za każdym razem, gdy skonstruowane są podstawowe podobiekty, jeśli istnieje wiele poziomów wyprowadzania? – fengqi

2

to inicjowane pomiędzy konstruktorów podstawy i klasy pochodnych:

class Base { Base() { } virtual void f(); }; 
class Derived { Derived(); virtual void f(); }; 

Dzieje się tak, gdy pamięć surowy przekształcić w obiekt Base. Zdarza się, gdy obiekt Base jest konwertowany na obiekt pochodny podczas konstruowania obiektu. To samo dzieje się na odwrót podczas niszczenia obiektu. To znaczy. przy każdej zmianie typu zmienia się wskaźnik vtable . (Jestem pewien, że ktoś komentuje, że vtables nie muszą istnieć zgodnie ze standardem ..)

0

This msdn article explains it in great detali

Tam jest napisane:

"i ostateczna odpowiedź brzmi ... jak można się spodziewać Zdarza się w konstruktora.".

czyli ..
A :: A(): i (0), j (0)
{ - >> tutaj!
// ...
//
}

Ale uważaj, powiedzmy masz klasy A i klasy A1 pochodzi od A.

  • Jeśli tworzysz nowy obiektu, vptr zostanie ustawiony na samym początku konstruktora klasy a
  • Ale jeśli było utworzyć nowy obiekt A1:

„Oto cała sekwencja zdarzeń podczas konstruowania instancję klasy A1:

  1. A1 :: A1 wywołuje ::
  2. A :: A zestawy vtable do A za vtable
  3. A: : a sporządzi i zwróci
  4. A1 :: A1 ustawia vtable do vtable
  5. A1 :: A1 sporządzi i zwrotów A1 za "
+1

Pierwszy standardowy cytat, który podałem w mojej odpowiedzi, pokazuje, że twoje wyjaśnienie nie jest całkiem poprawne. Gdy dodajesz późną odpowiedź, dobrze jest przeczytać i zrozumieć istniejące odpowiedzi, na wszelki wypadek. –

Powiązane problemy