присвоение указателя производного класса указателю базового класса в переполнении стека

У меня есть следующие

class base
{
};

class derived : public base
{
public:
derived() {}
void myFunc() { cout << "My derived function" << std::endl; }

};

Теперь у меня есть

base* pbase = new dervied();
pbase->myFunc();

Я получаю сообщение об ошибке myFunc не является функцией члена базы.

Как этого избежать? и как заставить myFunc вызываться?

Обратите внимание, у меня должен быть базовый класс, не содержащий функции, так как он является частью дизайна, а код выше является частью большой функции.

3

Решение

Если вы непреклонны в том, что эта функция НЕ должна быть частью базы, у вас есть только два варианта сделать это.

Либо используйте указатель на производный класс

derived* pDerived = new dervied();
pDerived->myFunc();

Или же (уродливее & сильно обескураженный) static_cast указатель до производного типа класса и затем вызов функции
НОТА: Использоваться с осторожностью. Используйте только тогда, когда вы УВЕРЕНЫ в типе указателя, который вы используете, то есть вы уверены, что pbase это derived или тип, полученный из derived, В данном конкретном случае это нормально, но я предполагаю, что это только пример реального кода.

base* pbase = new dervied();
static_cast<derived*>(pbase)->myFunc();
4

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

myfunc должен быть доступен из базового класса, поэтому вы должны объявить публичный виртуальный myfunc в base, Вы могли бы сделать это чисто виртуальным, если вы собираетесь base быть абстрактным базовым классом, т.е. классом, который не может быть создан и действует как интерфейс:

class base
{
public:
virtual void myfunc() = 0; // pure virtual method
};

Если вы муравей, чтобы иметь возможность создавать base объекты, то вы должны предоставить реализацию для myfunc:

class base
{
public:
virtual void myfunc() {}; // virtual method with empty implementation
};

Есть нет другого чистого способа сделать это если вы хотите получить доступ к функции из указателя на базовый класс. Самый безопасный вариант — использовать dynamic_cast

base* pbase = new derived;

....
derived* pderived = dynamic_cast<derived*>(pbase);
if (derived) {
// do something
} else {
// error
}
3

Чтобы использовать указатель базового класса, вы должен измените определение базового класса на:

class base
{
public:
virtual void myFunc() { }
};

Я не вижу другого способа обойти это. Сожалею.

2

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

class base
{
public:
virtual ~base(){};
virtual void myFunc() = 0;
};

class derived : public base
{
public:
derived() {}
void myFunc() { cout << "My derived function" << std::endl; }

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