The problem is that i want to list elements from a class named Resource;
In another class I have a function for this: void KeyDistributionCenter::ListResources()
and i want to call a function called PRINT from derived class File or from class Server. Class Server and File are derived from Resources.
I want to do this because in my derived class I have a PRINT function modified.(in File I print output file for example and in Server just general stuffs).
In KeyDistributionCenter i have a list of Resources(not a list of derived File or Server). So how i know which print to call(what derived class is from Resources) and how can i do this? Thanks!
Edit: My function print from Resources is virtual void print(); And i was thinking that if i declared like that it will know to acces print() function from File or Server.
Edit 2: To be more precise: i have another function RegisterResource(Resource &R) in my KeyDistributionCenter which add Resources to my std::vector resources(also vector is from KDC); Let s say i have a Resource File and all I want is when i call Print() function from KeyDistributionCenter(whit my vector list of Resources) to know what kind of Resource is and to call the print() function from File or Server class
Classic case for polymorphism:
class Resource
{
public:
virtual ~Resource() { }
virtual void print() = 0;
};
class Server : public Resource
{
public:
void print() override { std::cout << "server" << std::endl; }
};
class File : public Resource
{
public:
void print() override { std::cout << "file" << std::endl; }
};
You just need to make sure that Resource
class provides a virtual print
function in its interface (in above example, it's pure virtual, but that's not mandatory).
Now you can e. g. have:
std::unique_ptr<Resource> r = new Server();
r->print();
r = new File();
r->print();
Important: You need to refer to your objects via pointers or references. If you don't, then you'll encounter a phenomenon called 'object slicing':
Resource r = Server(); // server part in r will be sliced away and a pure
// Resource object remains!!!
This will happen, too, if you have some STL container of Resource
type:
std::vector<Resource> resources;
(you won't be able to do so at all, though, if your class is abstract, i. e. contains pure virtual functions – to be precise: you can create the vector, but cannot place elements into).
Edit: As denoted in comments already, the object-slicing is what actually occurred in your implementation. You need to re-design. One variant might look like this:
std::vector<std::unique_ptr<Resource>> resources;
void registerResource(std::unique_ptr<Resource> r)
{
resources.emplace_back(std::move(r));
}
registerResource(std::make_unique<Server>());
registerResource(std::make_unique<File>());
This scenario transfers ownership of the resources to the vector, it might cover your needs or not. There are numerous other variants possible, but whatever you do, you need either pointer (smart or not) or references in your vector.