Полиморфизм времени компиляции без использования виртуальных функций
Немного об использовании константных ссылок
Рассмотрим такой фрагмент кода:
struct A {
A() {};
~A() { ::std::cout << "A::~A()\n"; }
};
struct B : public A {
B() {};
~B() { ::std::cout << "B::~B()\n"; }
};
int main(void)
{
{
const A& a = B();
}
return 0;
}
Вопрос: что будет выведено в результате выполнения кода?
Правильный ответ:
A::~A()
Почему? Стандарт языка C++ указывает, что привязка временного объекта к константной ссылке увеличивает время жизни объекта до времени жизни константной ссылки.
Из кода нельзя убрать const, потому что в присваивании вызов конструктора возвращает, по сути дела, временный объект (rvalue в терминологии стандарта), а привязывать к неконстантным ссылкам можно только lvalue.
Есть маленький нюанс: вышесказанное не применимо к членам класса:
#include <string>
struct A {
A(void) { ::std::cout << "A::A()\n"; };
~A() { ::std::cout << "A::~A()\n"; }
};
struct B {
const A& a;
B(const A& ra) : a(ra) {};
~B() { ::std::cout << a.s << "\nB::~B()\n"; }
};
int main(void)
{
B b(A("test"));
return 0;
}
Деструктор A::~A() будет вызван после выполнения конструктора B::B(), это надо иметь в виду.
В случае, когда ссылка покидает пределы видимости, компилятор вызовет тот же деструктор, что и для временного объекта (на который эта ссылка ссылается). В результате мы получаем вызов правильного деструктора без виртуальных функций и расходов, с ними связанных.
Тем не менее, настоящим полиморфизмом это назвать нельзя. Рассмотрим пример:
struct A {
A() {};
~A() { ::std::cout << "A::~A()\n"; }
void test(void) const { ::std::cout << "A::test()\n"; }
};
struct B : public A {
B() {};
~B() { ::std::cout << "B::~B()\n"; }
void test(void) const { ::std::cout << "B::test()\n"; }
};
int main(void)
{
const A& a = B();
a.test();
return 0;
}
Метод test просто обязан быть константным, ибо при использовании константной ссылки мы имеем дело с константным объектом.
Такой код выдаст следующий результат:
B::~B()
A::~A()
Как видим, полноценного полиморфизма не получается.
Всё же интересно, какое применение данному подходу можно найти?
Автор: Vladimir; опубликовано в: C/C++; метки: C/C++, полиморфизмАпр
2009
Комментарии к статье «Полиморфизм времени компиляции без использования виртуальных функций» »
Пожалуйста, не используйте эту форму для комментирования! Данная форма предназначена исключительно для ботов.
Оставить комментарий к записи «Полиморфизм времени компиляции без использования виртуальных функций»
गते गते पारगते पारसंगते बोधि स्वाहा
Меня зовут Владимир, я программист-фрилансер, специализирующийся на Web-программировании и програмировании под Linux.
По совместительству занимаюсь администрированием LAMP/LNMP-серверов и техническим переводом.

