В C++, когда виртуальная функция может использовать статическое связывание? Если к нему обращаются через указатель, доступ к которому осуществляется напрямую или никогда?В C++, если функция-член является виртуальной, когда можно использовать статическое связывание?
ответ
Статическое связывание может быть выполнено только в том случае, если тип объекта полностью недвусмыслен во время компиляции. Я могу только думать о четырех местах, где тип абстрактного объекта недвусмыслен: в конструкторе, в деструкторе, при объявлении локально и в пределах той же области, что и динамическое распределение. Я не очень хорошо знаю этот стандарт, поэтому я не мог сказать, что он говорит об этих четырех возможностях (я бы сказал, что первые два являются статически связанными, третий возможный статически связан и последний нет, хотя, вероятно, он говорит, что он не определен или зависит от реализации). Помимо этих точек объект, к которому осуществляется доступ через указатель базового класса, может указывать на производный класс, а текущая единица перевода не знает, поэтому статическая привязка невозможна. Функция может быть вызвана с указателем на базовый класс в одном экземпляре и указателем на производный класс в другом!
Если вы хотите, чтобы вызвать версию базового класса функции, вы можете сделать это, явно называя базовый класс:
class Base
{
public:
virtual ~Base() {}
virtual void DoIt() { printf("In Base::DoIt()\n"); }
};
class Derived : public Base
{
public:
virtual void DoIt() { printf("In Derived::DoIt()\n"); }
};
Base *basePtr = new Derived;
basePtr->DoIt(); // Calls Derived::DoIt() through virtual function call
basePtr->Base::DoIt(); // Explicitly calls Base::DoIt() using normal function call
delete basePtr;
Hah, я был в середине набора почти точно такого же сообщения! Упрекнул вас. – 2008-11-06 00:15:18
Когда виртуальный метод вызывается с помощью указателя или ссылки, динамическое связывание используемый. В любое другое время используется привязка времени компиляции. Пример:
class C;
void Foo(C* a, C& b, C c) {
a->foo(); // dynamic
b.foo(); // dynamic
c.foo(); // static (compile-time)
}
Оптимизатор может вставлять различные области с помощью вставки. Если тип известен в одной из этих областей, он будет известен в плавкой области. – MSalters 2008-11-06 10:52:55