Рассмотрим следующий фрагмент:
#include<cstdio>
#include<iostream>
using namespace std;
class Class1{
public:
virtual void print(){
cout << "Class1"<<endl;
printf("%p\n", &Class1::print);
}
};
class Class2{
public:
virtual void print(){
cout << "Class2"<<endl;
printf("%p\n", &Class2::print);
}
};
class Class3{
public:
virtual void print(){
cout << "Class3"<<endl;
printf("%p\n", &Class3::print);
}
};
int main(){
Class1 c1;
Class2 c2;
Class3 c3;
c1.print();
c2.print();
c3.print();
}
Я скомпилировал следующий код на g ++ (MinGW) 8.2.0 и запустил вывод для cmd и Powershell. (Я не уверен, имеет ли это значение вообще.)
Я ожидал, что три напечатанных адреса будут разными. Однако три напечатанных адреса одинаковы, в моем случае «00000001», что тоже кажется странным, потому что это не похоже на действительный адрес (не кратный 4)
- Это происходит только при использовании ключевого слова "virtual".
- Независимо от того, наследует ли Class2 от Class1, не имеет значения. (То же самое с 2-3, 1-3 и т. Д.)
Насколько я знаю, виртуальные функции реализованы с помощью чего-то, называемого vtable. Я знаю, что для каждого класса есть секретный указатель, который указывает на таблицу. Но даже если это так, не должны ли адреса для каждой функции быть разными или хотя бы законными?
Я изучил другие вопросы, такие как: this , в котором функция fork () была в центре вопроса; это .. и, посмотрев на все эти вопросы, спрашивающие об «одном и том же адресе», я подумал: может быть, это как-то связано с ОС? Но после этого я не смог найти ничего подходящего.
TL; DR:
1. Приведенный выше код печатает три одинаковых адреса. Зачем? Как это возможно?
2. Напечатанный адрес выглядит недействительным (00000001). Почему это?