Форум программистов, компьютерный форум CyberForum.ru

Методы вызываются через указатель на объект класса; Как компилятор определяет, какой из методов надо вызвать? - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ кодировка русского шрифта http://www.cyberforum.ru/cpp-beginners/thread804419.html
/*вроде в консоли выходят русский шрифт, но когда выводится новый массив то выходят какие каракули) посмотрите пожалуйста кто умеет*/ #include <iostream> using namespace std; struct WORKER { char surname; // фамилия char initials; // инициалы char post; // должность int date; // год рождения
C++ Класс таблиц баз данных и класс записей в таблице(реляционная таблица). Предусмотреть класс связей между таблицами Здравствуйте! Никак не могу продумать структуру этой программы. Проходим наследование, но я все равно не знаю, как его здесь применить. Как нужно построить эти классы, чтобы получилась грамотная иерархия? Как вообще должен выглядеть класс связей между таблицами? Я долго билась над этим, но пока получился только трехмерный динамический массив. Вот код, я его забросила, очевидно, что это бред... http://www.cyberforum.ru/cpp-beginners/thread804360.html
Компилятор Borland C++
Создал программу, которая записывает определённые значения в файл. ofstream fout("out.txt", ios::out); То есть эта запись означает, что файл должен создаться(и записываться), в той папке, в которой лежит соответствующий исполняемый модуль. Сначала у меня и исполняемые модули не появлялись в папке, они находились в папке BIN , через опции я явно указал директорию, в которой должны...
C++ Обращение к элементам массива структур
Вводим n-ое количество имен и количество оценок каждому из имен.(студент - оценки) #include <iostream> using namespace std; int main() { int i,j,k,n=2; int sr;
C++ Косинус 90 градусов равняется бреду http://www.cyberforum.ru/cpp-beginners/thread804345.html
// var_7.cpp: определяет точку входа для консольного приложения. // #include "stdafx.h" #include <math.h> #define _USE_MATH_DEFINES #include <iostream> #include <conio.h> #include <iomanip>
C++ Перевод дробной части из десятичной в восьмеричною Отобразить этапи перевода дробной части из десятичной в восьмиричную. подробнее

Показать сообщение отдельно
Kastaneda
Форумчанин
Эксперт С++
4514 / 2856 / 228
Регистрация: 12.12.2009
Сообщений: 7,249
Записей в блоге: 1
Завершенные тесты: 1
10.03.2013, 10:24     Методы вызываются через указатель на объект класса; Как компилятор определяет, какой из методов надо вызвать?
Цитата Сообщение от kravam Посмотреть сообщение
Вы мне можете возразить- функции, которые вызовутся, определяются непосредственно во время исполнения. А вот ни фига подобного. Во время исполнения может быть определён тип статического классса, к которому будет неявно приведён указатель p- (тут, собсно, ничё нового. Но у меня для простоты один тип- stats). А вот функции, которые вызовутся, становятся известны только на этапе линковки и не позже!
Все не так. Адрес виртуальной функции определяется на этапе исполнения. Данная возможность реалиуется при помощи т.н. VPTR - указатель на таблицу виртуальных функций, который содержится в каждом объекте, если класс этого объекта содержит виртуальную функцию. Указатели ни к чему приводить не надо, просто смотриться VPTR по указателю и вызывается нужная функция.
Пример грязного использования VPTR - будет работать в MSVS, т.к. у них документировано, что VPTR располагается по нулевому смещение в объекте класса.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
 
class A {
public:
    virtual void foo()
    {
        std::cout << "A::foo()" << std::endl;
    }
};
 
class B : public A
{
public:
    virtual void foo()
    {
        std::cout << "B::foo()" << std::endl;
    }
};
 
int main ()
{
    A *ob = new B;
 
    ((void(*)())(***((void(***)())ob)))(); // вызываем B::foo() через VPTR
}
вобщем можешь погуглить в эту сторону, чтоб лучше понять.

Добавлено через 3 минуты
вот нагуглил.

Добавлено через 31 минуту
Поковырялся в ассемблере (в листинге для кода выше). Инициализация VPTR происходит так - сначала VPTR настраивается на таблицу для класса А (все адреса вычисляются на этапе компиляции), потом в конструкторе В (до начала выполнения самомого конструктора) VPTR переписывается на указатель на таблицу для класса В.
Увидел еще одну интересную вещь - везде пишут что сначала вызывается конструктор базового класса, потом для наследника. Конечно это все так, но интересно было увидеть как это реально сделано (как то раньше не обращал на это внимания). Для примера выше - сначала вызывается конструктор В, в нем есть некий код, который будет выполнен до начала выполнения самого тела конструктора и, кроме всего прочего, там есть явный вызов конструктора А, после выполнения конструктора А есть еще какой-то код и только после всего этого начинается выполнение тело конструктора В. Т.е. можно умудриться поставить breakpoint в конструкторе В еще до вызова конструктора А.
Я к тому, что
везде пишут что сначала вызывается конструктор базового класса, потом для наследника.
технически получается, что сначала вызывается конструкотр наследника, из него уже конструктор базового класса, а после этого начинается выполнение конструктора наследника.
Я конечно примерно так это все и представлял, но почему удивился
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru