Нужна ли виртуальная таблица для C ++?

У меня есть сомнения по поводу виртуальной таблицы C ++ в последнее время.

Почему C ++ использует виртуальную таблицу?

=> Потому что компилятор C ++ не знает фактический адрес функции

—> Почему?

=> Поскольку компилятор C ++ не знает точный тип (Cat? Dog? Animal?) Объекта, на который указывает указатель «panimal»

—Зачем? Это каким-то образом компилятор может выяснить тип объекта?

=> Да, я думаю, что компилятор может сделать это через тип отслеживаемого объекта.

Давайте рассмотрим источники, где указатель объекта получает свое значение. Действительно 2 источника.

  1. другой указатель
  2. адрес экземпляра класса
    Где «другой указатель» получает свое значение? В конце концов, есть указатель, который получает свое значение из «экземпляра класса».

Таким образом, путем отслеживания потока присваивания назад к исходному объекту

  => Компилятор может определить точный тип указателя.

  => компилятор знает адрес вызываемой функции

  => Виртуальная таблица не требуется.

Отслеживание типа объекта сохраняет как виртуальную таблицу, так и виртуальную таблицу, указатель каждого экземпляра класса.

Где не работает отслеживание типов объектов?

Связывание библиотек.

Если библиотечная функция возвращает указатель базового класса, компилятор не может отследить исходный объект-источник. Может компилятор может адаптироваться к коду библиотеки и коду без библиотеки. Для библиотечных классов, которые экспортируются, используйте виртуальную таблицу. Для других классов просто отслеживайте их тип объекта для экономии памяти.

Я не уверен, есть ли какая-либо ошибка в вышеприведенных утверждениях, пожалуйста, укажите ее, если таковая имеется Заранее спасибо ~

-2

Решение

В некоторых случаях, да, компилятор может определить тип, на который указывает указатель во время компиляции. Это довольно легко построить случай, когда он не может, хотя.

int x;
cin >> x;
Animal* p;
if (x == 10)
p = new Cat();
else
p = new Dog();

Если компилятор во всех случаях может доказать тип объекта, он может удалить виртуальные таблицы из своего сгенерированного кода в соответствии с правилом «как будто».

1

Другие решения

Компилятор может определить точный тип указателя.

да, но как вы хотите, чтобы он вызывал правильную функцию во время выполнения? Компилятор знает, но у С ++ нет виртуальной машины, которая могла бы сказать ему тип объекта, передаваемого во время выполнения, следовательно, потребность в виртуальной таблице для виртуальных функций унаследованных типов.
Вы бы предпочли, чтобы компилятор создавал код для всех различных путей кода, которые приводят к выполнению каждой виртуальной функции, чтобы он вызывал нужную функцию во время выполнения? Это привело бы к гораздо большим бинарным файлам, если это вообще возможно.

0

В этом примере становится ясно, что независимо от статического анализа кода, который может выполнить компилятор, фактический метод, вызываемый при ptrA-> f (); может быть известно только во время выполнения.

#include <sys/time.h>
#include <iostream>
#include <stdlib.h>

struct A {
virtual int f()
{
std::cout<<"class A\n";
}
};

struct B: public A {
int f()
{
std::cout<<"class B\n";
}
};

int main()
{
A objA;
B objB;
A* ptrA;

timeval tv;
gettimeofday(&tv, NULL);

unsigned int seed = (unsigned int)tv.tv_sec;
int randVal = rand_r(&seed);
if( randVal < RAND_MAX/2)
{
ptrA=&objA;
}
else
{
ptrA=&objB;
}

ptrA->f();
return 0;
}`
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector