Указатель типа объекта в наследовании

В этом коде я храню адрес объекта B в объекте типа указателя A.
Если я вызываю функцию, то программа должна запустить функцию второго класса, но она не работает и запустить функцию первого класса.
Если я ставлю виртуальный перед родительской функцией класса, то он перемещается в сторону другой функции класса.
Когда я сохранил адрес 2-го класса в объекте типа указателя, программа должна показать функцию 2-го класса. Но это не могло сделать это.
Почему это так?

#include<iostream>

using namespace std;
#include<conio.h>

class a
{
public:
void fun()
{
cout << "1st";
}
};

class b:public a
{
public:
void fun()
{
cout << "2nd";
}
};

class c :public a
{
public:
void fun()
{
cout << "3rd";
}
};

void main()
{
a *A;
b B;
c C;
A = &B;
A->fun();
_getch();
}

0

Решение

Когда я сохранил адрес 2-го класса в объекте типа указателя, программа должна показать функцию 2-го класса …

Нет, это не так. В C ++ функции связаны с классами (типами), а не объектами. Таким образом, компилятор смотрит на тип указателя, через который вызываются ваши функции. Затем он пытается найти такую ​​функцию в соответствующем определении класса.
В вашем случае компилятор видит «вызов функции fun() через указатель типа A «, и он просто переводит его на адрес fun() от class A,

* Вызываемая функция хранится в другом месте, но не внутри объекта.

Действительно, в этом и заключается смысл «статически типизированных» языков: компилятор смотрит на ваш объект через призму типа объекта.

Однако, как уже упоминалось, если вы хотите связать функцию с конкретным объектом, вам нужно использовать ключевое слово virtual, Это создаст виртуальную таблицу для каждого объекта класса A (и всех унаследованных от A). Тогда адреса всех функций помечены virtual будет храниться внутри этой виртуальной таблицы. Следовательно, когда наследующий класс имеет собственную реализацию виртуальной функции, адрес новой реализации будет override предыдущий адрес внутри виртуальной таблицы объекта.

Теперь, когда вы звоните fun() через указатель class A поток управления (теперь во время выполнения) выполнит поиск виртуальной таблицы объектов и найдет адрес ожидаемой функции.

class A
{
public:
virtual void fun()
{
cout << "1st";
}
};
class B
{
public:
void func() override
{
cout << "2nd";
}
}
void main()
{
a *A;
b B;
A = &B;
A->fun();  // -> "2nd"// function address deduced at runtime
}
1

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

Вам нужно использовать virtual ключевое слово, иначе наследование может работать не так, как вы ожидали.

Так что поменяй class a следующее:

class a
{
public:
virtual void fun()
{
0

В c ++ указатели являются статическими. Это означает, что они всегда ищут родительские функции, даже если они указывают на дочерний класс. Вы можете избежать этого, объявив: fun as виртуальный. Взгляните на это:
http://www.cplusplus.com/doc/tutorial/polymorphism/

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector