2017-01-06 2 views
1

У меня есть два класса.Наследование C++

class A: 

class B: public A 
{ 
    //new function 
    void setHint(...); 
} 

И иметь данные структуры.

typedef std::shared_ptr<A> window_ptr; 
std::stack<window_ptr> m_windowsStack; 
m_windowsStack.push(std::make_shared<A>("Hint")); 
m_windowsStack.push(std::make_shared<B>("Game")); 

И есть функция поиска в стеке:

std::shared_ptr<A> WindowManager::findWindow(std::string title) 
{ 
    ... return result; 
} 

И использовать функцию находят элемент в стеке:

auto w = findWindow("Game"); //return element type B 
w->setHint(window); 

Но оказывается, что функция FindWindow возврата type A. Я получаю ошибку "" класс А 'не имеет члена с именем' setHint ' w-> setHint (window); "

Должен ли я объявлять функцию setHint в классе A как виртуальную функцию? Как заставить переменную автоматически понимать, что она относится к типу B?

+1

Просто введите результат, т. Е. 'Auto w = findWindow (« Игра »);' -> 'auto w = static_cast (findWindow (« Game »));' – George

+1

'class A:' это ошибка, напишите реальный код. Кроме того, я не уверен, что вы хотите, чтобы 'setHint' был вариационной функцией. –

+0

@ M.M класс A: {} это абстрактный класс, мой класс большой, и для этого вопроса \ функции много ненужных переменных. :) –

ответ

2

Ваш выбор:

  1. Declare setHint виртуального класса А в

  2. Использование dynamic_pointer_cast

Таким образом

auto w = std::dynamic_pointer_cast<B>(findWindow("Game")); 
assert(w); // Will be nullptr if cast fails. 
w->setHint(window); 
5

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

class A { 
public: 
    virtual void setHint(/*...*/) { /* some default implementation */} 
    // or pure virtual 
    virtual void setHint(/*...*/) = 0; 

    virtual ~A() = default; // base class should have a virtual destructor 
}; 

class B: public A { 
public: 
    void setHint(/*...*/) override; 
}; 

В качестве альтернативы, если вы знаете наверняка, что тип указывал на возвращаемое значение из findWindow является B вы можете просто static_pointer_cast его вниз

auto w = std::static_pointer_cast<B>(findWindow("Game")); 
w->setHint(window); 

Если вы не уверены, и A является полиморфным типом (с любыми функциями virtual), вы можете указать номер dynamic_pointer_cast и указать нуль

if (auto w = std::dynamic_pointer_cast<B>(findWindow("Game"))) { 
    w->setHint(window); 
} 
+0

другой вариант - 'dynamic_cast (* w) .setHint (window);' - это будет генерировать исключение вместо неопределенного поведения в случае, если он не является ожидаемым типом –

+0

@MM, но нет, если OP пытается не добавлять виртуальные функции –

+0

Он сказал в комментарии к вопросу о том, что A является абстрактным классом (подразумевая, что он уже содержит виртуальные функции) –

Смежные вопросы