C++ 3d.Комментарии



"Виртуальные конструкторы"


... допускаются некоторые ослабления по отношению к типу возвращаемого значения.

Следует отметить, что эти "некоторые ослабления" не являются простой формальностью. Рассмотрим следующий пример: #include <stdio.h>

struct B1 { int b1; // непустая virtual ~B1() { } };

struct B2 { int b2; // непустая

virtual B2* vfun() { printf("B2::vfun()\n"); // этого мы не должны увидеть return this; } };

struct D : B1, B2 { // множественное наследование от непустых классов virtual D* vfun() { printf("D::vfun(): this=%p\n", this); return this; } };

int main() { D d;

D* dptr=&d; printf("dptr\t%p\n", dptr);

void* ptr1=dptr->vfun(); printf("ptr1\t%p\n", ptr1);

B2* b2ptr=&d; printf("b2ptr\t%p\n", b2ptr);

void* ptr2=b2ptr->vfun(); printf("ptr2\t%p\n", ptr2); }

Обратите внимание: в данном примере я воспользовался "некоторыми ослаблениями" для типа возвращаемого значения D::vfun(), и вот к чему это привело: dptr 0012FF6C D::vfun(): this=0012FF6C ptr1 0012FF6C

b2ptr 0012FF70 D::vfun(): this=0012FF6C ptr2 0012FF70

Т.о. оба раза была вызвана D::vfun(), но возвращаемое ей значение зависит от способа вызова (ptr1!=ptr2), как это, собственно говоря, и должно быть.

Делается это точно так же, как уже было описано в разделе 361 "12.2.6. Виртуальные функции", только помимо корректировки принимаемого значения this необходимо дополнительно произвести корректировку this возвращаемого. Понятно, что виртуальные функции с ковариантным типом возврата встречаются настолько редко, что реализация их вызова посредством расширения vtbl вряд ли может быть признана адекватной. На практике обычно создаются специальные функции-заглушки, чьи адреса помещаются в соответствующие элементы vtbl: // псевдокод

// оригинальная D::vfun, написанная программистом D* D::vfun(D *const this) { // ... }

// сгенерированная компилятором функция-заглушка для вызова D::vfun() через // указатель на базовый класс B2 B2* D::vfun_stub(B2 *const this) { return D::vfun(this+delta_1)+delta_2; }




Содержание  Назад  Вперед