Reputation: 695
I have two class.
class A:
class B: public A
{
//new function
void setHint(...);
}
And have struct data.
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"));
And have function find in stack:
std::shared_ptr<A> WindowManager::findWindow(std::string title)
{
... return result;
}
And use function for find element in stack:
auto w = findWindow("Game"); //return element type B
w->setHint(window);
But it turns out that function findWindow return type A
. I get error "'class A' has no member named 'setHint'
w->setHint(window);"
Do I need to declare setHint function in class A as virtual function? How do I make a variable to automatically understand that it is of type B?
Upvotes: 1
Views: 153
Reputation: 36882
Without understanding your entire project, I'd say the right solution is likely to add a virtual function in the base class.
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;
};
Alternatively, If you know for sure that the type pointed to the return value from findWindow
is a B
you can simply static_pointer_cast
it down
auto w = std::static_pointer_cast<B>(findWindow("Game"));
w->setHint(window);
If you aren't sure, and A
is a polymorphic type (having any virtual
functions) you can dynamic_pointer_cast
and check for null
if (auto w = std::dynamic_pointer_cast<B>(findWindow("Game"))) {
w->setHint(window);
}
Upvotes: 5
Reputation: 29017
Your choices are:
Declare setHint
virtual in class A
Use dynamic_pointer_cast
Thus
auto w = std::dynamic_pointer_cast<B>(findWindow("Game"));
assert(w); // Will be nullptr if cast fails.
w->setHint(window);
Upvotes: 2