Информация об изменениях

Сообщение Как удаляется vptr? от 10.04.2023 16:33

Изменено 10.04.2023 16:35 avovana

Как удаляется vptr?
Привет с собеседования в тинькове.

Где есть вообще этот vptr?
Если делаем объект базового класса, у которого хотя бы 1 функция virtual, то компилятор добавит ему vptr.
Размер такого класса(если нет других членов) станет из 1 байта -> sizeof(vptr).
Если делаем объект класса наследника от такого базового класса, то компилятор добавит ему vptr. У него не будет ещё 1ого vptr от базового.
Т.е. это член объекта наследника.
Что если удаляем теперь наследника как в коде ниже. То есть, не будет вызван деструктор класса наследника. Что станет с этим vptr? Утечёт?

#include <iostream> 
   
class Base { 
    virtual void print() {std::cout << "from Base" << std::endl;} 
public: 
    Base() {print();} 
    virtual ~Base() { print(); } 
    void basePrint() { print(); } 
}; 
   
class Derived : public Base { 
    virtual void print() {std::cout << "from Derived" << std::endl;} 
public: 
    Derived () { print(); } 
    ~Derived () { print(); } 
}; 
   
int main(void) { 
    Base* base = new Derived; 
    base->basePrint(); 
    delete base; 
    return 0; 
}


Видел пример в интернете, что vptr 1 в базовом классе. Наследуется наследниками. Т.е. деструктор базового класса по любому вызовется. И удалит этот vptr.

Ещё как-то был вопрос: "Где хранится таблица виртуальных методов?".
Как удаляется vptr?
Привет с собеседования в тинькове.

Где есть вообще этот vptr?
Если делаем объект базового класса, у которого хотя бы 1 функция virtual, то компилятор добавит ему vptr.
Размер такого класса(если нет других членов) станет из 1 байта -> sizeof(vptr).
Если делаем объект класса наследника от такого базового класса, то компилятор добавит ему vptr. У него не будет ещё 1ого vptr от базового. А будет свой vptr.
Т.е. это член объекта наследника.
Что если удаляем теперь наследника как в коде ниже. То есть, не будет вызван деструктор класса наследника. Что станет с этим vptr? Утечёт?

#include <iostream> 
   
class Base { 
    virtual void print() {std::cout << "from Base" << std::endl;} 
public: 
    Base() {print();} 
    virtual ~Base() { print(); } 
    void basePrint() { print(); } 
}; 
   
class Derived : public Base { 
    virtual void print() {std::cout << "from Derived" << std::endl;} 
public: 
    Derived () { print(); } 
    ~Derived () { print(); } 
}; 
   
int main(void) { 
    Base* base = new Derived; 
    base->basePrint(); 
    delete base; 
    return 0; 
}


Видел пример в интернете, что vptr 1 в базовом классе. Наследуется наследниками. Т.е. деструктор базового класса по любому вызовется. И удалит этот vptr.

Ещё как-то был вопрос: "Где хранится таблица виртуальных методов?".