Reputation: 532
I'm trying to make a kind of "collection". This class needs to accept all classes that inherits from a base class.
For example:
Imagine that we have a base class called "A", and we have a lot of other classes that inherits from this class "A". So we have, class "B" that inherits from "A", class "C" that inherits from "A", and so on, and we have a class called "collection" that also inherits from "A". The class "collection" has a "std::map" where keep all classes saved using the "add" method and can be retrieved using "get".
What is happening is that it works somehow, but the application converts to the "base class" instead of return the class that is passed.
Let's go to the code (see the comments on the code to understand the output):
This is the working code:
#include <iostream>
#include <string>
#include <map>
class A
{
public:
virtual void saySomething()
{
std::cout << "Hello from A object" << std::endl;
}
};
class B : public A
{
public:
void saySomething()
{
std::cout << "Hello from B object" << std::endl;
}
};
class C : public A
{
void saySomething()
{
std::cout << "Hello from C object" << std::endl;
}
};
class Collection : public A
{
public:
void add(const std::string & key, A * value)
{
storage[key] = value;
}
A * get(const std::string & key)
{
return storage[key];
}
private:
std::map<std::string, A *> storage;
};
int main( int argc, char ** argv )
{
B * b = new B;
C * c = new C;
Collection * col = new Collection;
Collection * col2 = new Collection;
col->add("b", b); // works, because "b" inherits from "A" class.
col->add("c", c); // works, because "c" inherits from "A" class.
col->add("col2", col2); // watch this part...
col->get("b")->saySomething(); // works - Output: Hello from B object
col->get("c")->saySomething(); // works - Output: Hello from C object
return 0;
}
It works, but when I try to retrieve the "col2" and use his methods...
col->get("col2")->add("b", b);
// output: error: 'class A' has no member named 'add'
If I'm not wrong, it needed to works, because the "get" method returns the object, so I have the methods of the "col2" object right? If you answer yes, we have the same thought, and I have no idea what is happening. On the "b" and "c" object it returns the object and I have the "saySomething" methods, but when i try to retrieve the "col2", it has the object as an "A" object, so the error:
'class A' has no member named 'add'
And it get worse if I do this:
col->get("col2")->saySomething(); // output: Hello from A object
The idea is that, a collection that accepts only classes that inherits from a base class and also accepts others collections that inherits from the same base class, like recursively.
Upvotes: 0
Views: 93
Reputation: 20993
C++ has static typing, so when you have an object of type A
- and this is what your get
method returns - only methods declared in A
can be used. To call add
on the result of get
you either need to cast with static_cast
or dynamic_cast
, or rethink your class hierarchy altogether. Why Collection
needs to inherit from A
? (And to answer your last question, since it inherits, if you call saySomething
it will call the method declared in A
because Collection
does not provide its own override).
Upvotes: 2