getting all objects of a classes in C++ - c++

Is there a way through which we can get all the objects of a class in C++.Like in Python we can do
class_name.objects.all()
to get all the objects of a class.What's its analog in C++,if it exists?

You can do this yourself, but make sure you know what you're doing.
How:
There's nothing within C++ that already does this, but it's pretty easy to do this yourself. The key is to recognize that a class can have static member variables and functions (i.e. functions that belong to the whole class, rather than to individual objects of the class).
So you can use some kind of table or other data structure to store a reference to each object. Like so:
class A {
public:
//constructor assigns this object an id based on the static value curID,
//which is common to the class (i.e. the next class to call the constructor
//will be assigned an id thats 1 more than this one
//also, constructor adds the pointer to this object to a static map of ids
//to objects. This way, the map can be queried for the pointer to an object
//that has a particular id
A() {
id = curID++;
objects[id] = this;
}
//copy constructor ensures an object copied from another does not
//take the id of the other object, and gets added to the map
A(const A&) {
id = curID++; //don't want have the same ID as the object we are copying from
objects[id] = this;
x = A.x;
y = A.y;
}
A& operator=(const A&) {
id = curID++;
objects[id] = this;
x = A.x;
y = A.y;
return *this;
}
//destructor removes the pointer to this object from the map
~A() {
objects.erase(id);
}
//function to get the map that stores all the objects
static map<int, A*>& GetMapOfObjects() {
return objects;
}
private:
//the following variable is **static**, which means it does not
//belong to a single object but to the whole class. Here, it is
//used to generate a unique ID for every new object that's
//instantiated. If you have a lot of objects (e.g. more than
//32,767), consider using a long int
static int curID;
//this variable is also static, and is map that stores a pointer
//to each object. This way, you can access the pointer to a
//particular object using its ID. Depending on what you need, you
//could use other structures than a map
static map<int, A*> objects;
//this is a (non-static) member variable, i.e. unique to each object.
//Its value is determined in the constructor, making use of curID.
int id;
//these are some other member variables, depending on what your object actually is
double x;
double y;
}
Note: The above design is very basic and not complete, but just meant to give you an idea of how to implement what you're asking for using static members/functions. For example, for operations that you want to perform on all the objects, for example, it may be better to implement a static function that iterates through the map of elements, rather than getting the map and then doing the iterations "outside".
Why:
I've never used this method myself, but one potential use case I can think of is e.g. in a graphics or game application, where you may want to only draw objects that are in scope and change certain drawing-related properties of all of them at once, e.g. color or size. I'm working on an application that might eventually need something like this (sort of a visual debugger). I'm sure people can provide more examples in the comments.
Why not:
The picture gets complicated when inheritance is involved.
If you have a class B that derives from A (i.e. B "is an" A), then who should keep track of objects of B? A static member of objects in A, or a similar one in B, or both?
Let's say both. Then what happens if a static function that applies to all objects in A calls a virtual member function on each object? If the virtual function has been overridden in the derived class, then that function will be called instead for all objects being tracked in class A that are actually B objects. What happens if you then call that function again in another static function in B?

There is no way that I know of but you can implement one with static members
#include <iostream>
#include <vector>
class MyClass{
private:
static std::vector<MyClass*> objList;
public:
MyClass() {
objList.push_back(this);
}
static std::vector<MyClass*> getAllObjects(){
return objList;
}
};
std::vector<MyClass*> MyClass::objList;
main(){
MyClass m,a;
for (int i=0;i<MyClass::getAllObjects().size();i++){
std::cout<<MyClass::getAllObjects()[i]<<std::endl;
}
}

No, unless you implement this mechanism yourself. By default it is not provided by C++ language.
You CAN implement this mechanism yourself quite easily - register class in some kind of table within constructor, unregister within destructor. As long as you follow rule of Three, it'll work fine.

Of course there is. Just use Factory pattern to create and destroy all your objects and, in Factory implementation, return a collection of live objects in a Factory function that you will provide.

As has already been stated C++ does not provide a mechanism to do this automatically. However (again has already been stated in the comments) you can use one of the standard library containers to maintain a list of created objects and then register them in the constructor and unregister them in the destructor. The example below shows one way to do this...
#include <iostream>
#include <memory>
#include <utility>
#include <map>
#include <algorithm>
#include <iterator>
#include <typeinfo>
#include <vector>
class Object
{
static std::map<const Object*, Object*> objects_;
public:
Object()
{
objects_.insert(std::make_pair(this, this));
}
virtual ~Object()
{
objects_.erase(this);
}
static std::vector<Object*> get_all()
{
std::vector<Object*> o;
o.reserve(objects_.size());
for (auto obj : objects_)
{
o.push_back(obj.second);
}
return std::move(o);
}
template<class Type>
static std::vector<Type*> get_bytype()
{
std::vector<Type*> o;
for(auto obj : objects_)
{
Type *t = dynamic_cast<Type*>(obj.second);
if (t != nullptr)
{
o.push_back(t);
}
};
return std::move(o);
}
void print() const
{
std::cout << "I'm a " << typeid(*this).name() << " object # " << this << std::endl;
}
};
std::map<const Object*, Object*> Object::objects_;
class Foo : public Object {};
class Bar : public Object {};
int main()
{
std::unique_ptr<Object> o1 = std::unique_ptr<Object>(new Foo());
std::unique_ptr<Object> o2 = std::unique_ptr<Object>(new Bar());
std::unique_ptr<Object> o3 = std::unique_ptr<Object>(new Foo());
std::unique_ptr<Object> o4 = std::unique_ptr<Object>(new Bar());
std::vector<Object*> objects = Object::get_all();
for (auto o : objects)
{
o->print();
}
std::cout << "-----" << std::endl;
std::vector<Foo*> foos = Object::get_bytype<Foo>();
for (auto o : foos)
{
o->print();
}
std::cout << "-----" << std::endl;
std::vector<Bar*> bars = Object::get_bytype<Bar>();
for (auto o : bars)
{
o->print();
}
}
The above example produces the following output
I'm a class Foo object # 003FED00
I'm a class Bar object # 003FED30
I'm a class Foo object # 003FED60
I'm a class Bar object # 003FED90
I'm a class Foo object # 003FED00
I'm a class Foo object # 003FED60
I'm a class Bar object # 003FED30
I'm a class Bar object # 003FED90

Related

c++ Mapping class to number

I recently started with c++ development. I've come to a problem of which I am not able to solve, given that I am unaware if the following is possible.
I want to create a mapping between a number and class, which are derived from an abstract class.
Essentially what I would like to be able to do is create a factory method that can create a new instance of a class based on a given number associated with that class.
I know that I could do the following...
Vehicle *Vehicle::from_type(byte type)
{
switch(type)
{
case 0x00: return new Bicyle();
case 0x01: return new Car();
...
case 0x10: return new Truck();
}
return null;
}
..., but I'd rather not as I want to keep it DRY.
It there a way where one can do something along the lines of this:
// I know this is incorrect syntax
const map<byte, class extends Vehicle> VEHICLE_MAPPING = {{0x00, Bicyle}, {0x01, Car}, ..., {0x10, Truck}};
Vehicle *Vehicle::from_type(byte type)
{
return new VEHICLE_MAPPING[type]();
}
I can see how your approach could work with usage of std::map<uint8_t, std::unique_ptr<Vehicle>>, but there is a problem - you wouldn't be able to initialise that map with initializer_list, since it copies the elements and, as we all know, std::unique_ptr cannot be copied. You would have to create an init() function to initialise the map that would use similar logic to your Vehicle *Vehicle::from_type(byte type), which would simply be pointless given you already have your function.
Furthermore, I disagree that your first solution violates DRY. It is actually correct in a sense that you won't be forced to use switch or ifs elsewhere in the code. I'd definitely stick with it.
The final note - you could use std::map<uint8_t, std::shared_ptr<Vehicle>> instead of std::map<uint8_t, std::unique_ptr<Vehicle>> and initialise it with initializer_list, since std::shared_ptr can be copied, but I wouldn't advise that since it wrongly indicates the usage of shared_ptr. If you somehow feel forced to do so, here is an example:
class Base{ public: virtual ~Base() = default; };
class Derived1 : public Base{};
class Derived2 : public Base{};
class derived_factory{
private:
derived_factory();
static inline std::map<uint8_t, std::shared_ptr<Base>> base_map = {
{0x00, std::make_shared<Derived1>()},
{0x01, std::make_shared<Derived2>()}
};
public:
static std::unique_ptr<Base> from_type(uint8_t type)
{
return std::make_unique<Base>(*base_map[type]);
}
};
int main()
{
auto ptr = derived_factory::from_type(0x00);
// ptr is of a type std::unique_ptr<Base> and points to Derived1 object
}
Additional note that should be a final discouragement of using this solution is that it's quite slow. It constructs the objects in a map and does nothing with them except for keeping them as 'templated' copy examples.
If they're all derived from a base class, you can use the factory pattern, e.g., from Loki's implementation (see Modern C++ Design for the details, though that book is pre-C++11).
The following creates some concrete vehicles and puts them in a vector and then calls the drive() method on each of them:
#include <iostream>
#include <memory>
#include <vector>
#include "factory.h"
struct Vehicle
{
virtual ~Vehicle() = default;
virtual void drive() = 0;
};
struct Car : Vehicle
{
static constexpr auto ID = 1;
void drive() override { std::cout << "Car\n"; }
};
struct Truck : Vehicle
{
static constexpr auto ID = 2;
void drive() override { std::cout << "Truck\n"; }
};
// Create the factory object
auto g_factory = MyUtil::Factory<std::unique_ptr<Vehicle>, int>{};
void RegisterTypesWithFactory()
{
// We pass in creator functions for each type. Note that these
// could be lambdas or some other freestanding function and they
// could accept parameters.
g_factory.Register( Car::ID, &std::make_unique<Car> );
g_factory.Register( Truck::ID, &std::make_unique<Truck> );
}
int main()
{
// Configure the factory
// Note: Registration can be done any time, e.g., later based on input
// from a file. I do them all at once here for convenience of illustration.
RegisterTypesWithFactory();
// Create some objects with the factory
auto vehicles = std::vector<std::unique_ptr<Vehicle>>{};
vehicles.emplace_back( g_factory.Create( Car::ID ) );
vehicles.emplace_back( g_factory.Create( Truck::ID ) );
// Do something with the objects
for( const auto& v : vehicles )
{
v->drive();
}
}
Which prints:
Car
Truck
See it run live on Wandbox.

Change the class of an object: possible with std::move?

I know that I cannot mess with the V-Table (in a somewhat sane way) once an object is created. Which means I have to copy an object to change it's type. Does this also hold true with c++11's std::move and friends?
class Base {
public:
virtual int type() = 0;
// more data members I want to avoid to copy
};
class D1 : public Base {
public:
int type() {
return 1;
}
};
class D2 : public D1 {
public:
int type() {
return 2;
}
};
int main()
{
// creating the actual object, type is D1
D1* obj = new D1();
// this is what does not work, I want to "change" the object to D2
D2* obj2 = &std::move<D2>(*obj);
// cast it to obj2 base class
Base* baseObj = static_cast<D1*>(obj2);
// now I want a "2" here
int t = baseObj->type();
printf ("%d\n", t);
}
I do not know the move semantics very well... But is there something I can change a D1 object into D2 (or vice versa) with type safety? (Both classes are virtually the same from the memory layout)
While you cannot change the type of an existing object, you can easily change the dynamic type of a pointer member and achieve the desired effect. This is known as strategy design pattern.
E.g.:
#include <memory>
#include <iostream>
class Host
{
struct Strategy
{
virtual ~Strategy() = default;
virtual int type() const = 0;
};
struct StrategyA : Strategy { int type() const override { return 1; } };
struct StrategyB : Strategy { int type() const override { return 2; } };
std::unique_ptr<Strategy> strategy_;
public:
Host()
: strategy_(new StrategyA)
{}
int type() const { return strategy_->type(); }
void change_strategy(int type) {
switch(type) {
case 1: strategy_.reset(new StrategyA); break;
case 2: strategy_.reset(new StrategyB); break;
default: std::abort();
}
}
};
int main() {
Host host;
std::cout << host.type() << '\n';
host.change_strategy(2);
std::cout << host.type() << '\n';
}
It seems to me you are not familiar with what std::move actually does.
As others have said, std::move doesn't actually move anything. It obtains an xvalue (a variable that has a name, but can have its resources reused or transfered to another object) reference from an lvalue (essentially a named variable), so, std::move is nothing but a cast. It doesn't create any new object. Read more about it here and here.
Still about move semantics topic,
std::move is mostly useful so that you can force rvalue-aware methods to receive and reuse resources in variables that you absolutely know that can have their resources moved.
To get a more indepth insight of this, I'd recommend reading What are move semantics?. For instance, one of its uses is creating an object from a temporary (e.g, objects created inside a function and then returned):
#include <vector>
#include <iostream>
class A {
public:
// A very large resource
std::vector<int> resource;
// Constructs our very large resource
A(): resource(1024, 0) { std::cout << "Default construct" << std::endl; }
// Move (reuses) a very large resource from an instance
A(A && other) : resource(std::move(other.resource)) {
std::cout << "Move construct" << std::endl;
}
};
Now, A's move constructor is only called when the other object is an rvalue (or an xvalue), such as:
A foo(A a) { return a; }
int main() {
A a = foo(A());
return 0
}
In this scenario, before foo() gets called, a temporary A() is created and passed in as argument. foo() returns it, but since it is a temporary , it fits as an rvalue and is passed to the move constructor of A when constructing A a = foo(A()).
Inside the move constructor of A(), std::move(other.resource) is used when constructing another resource to call the move constructor of std::vector so that it can try to use whatever it can from other.resource instead of creating everything from scratch again (and then copying).
But as stated previously, std::move on itself doesn't move anything, but it is there to convey intent to move, help the compiler do the right thing (and other programmers to read it and understand faster what you meant).
So, to answer your question directly, no, there isn't anything that'd let you transform an object into another, other than constructing a new object. If you are sure that you are going to destroy obj (which you are not doing, by the way), you can implement an constructor of D2 that accepts an rvalue of D1:
class D2 {
public:
D2(D1 && d1) : resource(std::move(d1.resource)) { d1.resource = nullptr; }
}
int main() {
D1 * obj = new D1();
D2 * obj2 = new D2(std::move(*obj));
delete obj;
}
There are other things to consider when doing this, though, such as destructors of moved objects and other details. I'd recommend reading more about the subject and also maybe using a different method of achieving what you are doing, such as the Strategy pattern mentioned in another answer.

How come accessing derived class member in base class pointer vector returns an error?

Streamlined Example of the problem:
#include <string>
#include <deque>
#include <iostream>
class Action{
public:
std::string name;
Action(std::string name){
this->name = name;
}
};
class Ability : public Action{
public:
int bar;
Ability(std::string name) : Action(name){}
};
int main(){
std::deque<Action*> foo;
Ability test("asdf");
test.bar = 122;
foo.push_back(&test);
std::cout << foo.at(0)->bar << std::endl;
return 0;
}
This creates an error, that there is no 'bar' member of 'Action'.
I realise that this relates to object slicing and I've attempted to use pointers, which allows the vector to push back the 'Ability' object but I cannot access its 'bar' member.
What am I missing?
First, a word from our sponsor: What is object slicing?
Now that you've read the above link, you can see that no slicing has taken place because the object was not copied into foo, only a pointer to the object was copied. The Ability is still intact, wherever in memory test sits.
But... Foo contains pointers to Action, not Ability. There is no way for a user of Foo to know if any given element of Foo is a reference to an Action, an Ability, or some other subclass of Action that they know absolutely nothing of. Very powerful stuff, the ability to work with something you don't even know exists, but this comes at a price: You have to work with it as something you do know. Users of Foo can only use the interface presented to them, that of Action. There are ways around this, such as dynamic_cast, but in most cases it best to stick with the provided interface and allow an overloaded method or operator to do black magic behind the scenes to do the correct thing for whatever the Action represents. If this means you have to
class Action{
public:
std::string name;
Action(std::string name){
this->name = name;
}
virtual int getbar() = 0; // pure virtual method that all subclasses
// of Action must implement
};
class Ability : public Action{
public:
int bar;
Ability(std::string name) : Action(name){}
int getbar()
{
return bar;
}
};
and later
std::cout << foo.at(0)->getbar() << std::endl;
so be it.

C++ Function with side-effect used at file scope, accesses singleton

I've written a class with the following static method:
MyMap& Manager::GetMap( void )
{
static MyMap* factories = new MyMap();
return ( *factories );
}
Where "MyMap" is a typedef for:
unordered_map<string, function<Base* ( Dependency& d )>>
There are also a variety of types derived from Base e.g.
class Derived1 : public Base
{
public:
Derived1( Dependency& d );
};
Consider the following usage.
I define the following in an implementation file for Derived1:
#include "Derived1.h"
#include "Manager.h"
int RegisterDerived1( void )
{
Manager::GetMap()["Test"] = []( Dependency& d ){ return new Derived1( d ); };
return 0;
}
int Reg = RegisterDerived1();
You can't call functions at file scope, but you can assign the return value of a function to a global variable even if that function has side effects. Hence, by the time that "Manager" is in use the "MyMap" will contain string/function pairs for various derived types of "Base" (so far). The intent is that new derived types of "Base" register themselves with "Manager", able to construct instances of that type and select which type based on a name.
I'm wondering if this represents safe behaviour and/or if there are alternative implementations to get the desired effect?
I've been made aware of this article that proposes a generic registration object that takes the above pair in its constructor and does the registering, a static instance of which is then defined for each class to be registered.
http://accu.org/index.php/journals/597
The principle is fine.
A few things you may want to consider:
returning raw pointers is a bad idea - use unique_ptr instead.
Did you really want the Dependency& reference to be non-const?
Hide the internal implementation. There's no need for users to know (or care) that it's an unordered_map.
A slightly modified version with inline comments for you to consider:
#include <functional>
#include <unordered_map>
#include <memory>
#include <string>
struct Base
{
virtual ~Base() = default;
};
struct Dependency
{
};
struct Manager
{
// I notice that Depdendency& is not const. Was that what you wanted?
using factory_function = std::function<std::unique_ptr<Base> ( Dependency& d )>;
// public registration function hides internal implementation of map
static bool register_function(const std::string ident, factory_function f)
{
return GetMap().emplace(std::move(ident), std::move(f)).second;
}
// public create function hides internal implementation of map
// returns a unique_ptr - much better!
static std::unique_ptr<Base> create(const std::string& ident, Dependency& d)
{
// this will throw an exception if the factory does not exist.
// another implementation could substitute a known version of Base,
// for example. But now it's under your control and the user does
// not have to think about it.
return GetMap().at(ident)(d);
}
private:
using MyMap = std::unordered_map<std::string, factory_function>;
// private map implementation. In future we may want to add a mutex
// (in case the map can be dynamically updated?)
// so let's encapsulate
static MyMap& GetMap()
{
// no need for new here. Static variables are cleanly destructed at
// the end of the program, and initialised the first time the code
// flows over them.
static MyMap _map;
return _map;
}
};
struct Derived1 : Base
{
Derived1(Dependency&) {}
};
// now we don't need to care about Manager's implementation.
// this is better - we are decoupled.
bool derived1_registered = Manager::register_function("Derived1",
[](Dependency& d)
{
return std::make_unique<Derived1>(d);
});
int main()
{
Dependency d;
auto p = Manager::create("Derived1", d);
return 0;
}

Use of static collections within a class to store class

I am reviewing some code and a common pattern I am seeing is where a collection of objects is stored as a static member of the class of object being stored.
If, for example, I have a class of objects: class widget, then a list of widgets would be stored as a static std::list within the widget class.
The obvious way to do this would be to have an application level (global level) std::list - and then to find an item lookup this application level list.
I can see that the static member collection idea is more convenient for the user of a. Are there other advantages? Are there other alternatives which should also be considered similar? What are the pros and cons of a and b approach?
Here are the two alternatives in code:
file a.hpp:
//Using collection as static member of class idea
class a {
public:
a();
~a();
class id2a_map;
static class id2a_map id_map;
static a* Find(unsigned id);
unsigned m_id;
};
file a.cpp:
#include <map>
#include "a.hpp"
class a::id2a_map : public std::map<int, a*>
{
};
a::id2a_map a::id_map;
a::a() {
static unsigned id_cnt = 0;
++id_cnt;
id_map.insert(id_map.end(), id2a_map::value_type(m_id = id_cnt, this));
}
a::~a() {
id_map.erase(m_id);
}
a* a::Find(unsigned id) {
id2a_map::iterator i = id_map.find(id);
return i==id_map.end() ? 0 : i->second;
}
file b.hpp:
// b class - not using static collection
class b {
public:
b(unsigned id) : m_id(id) { }
unsigned get_id() const { return m_id; }
private:
unsigned m_id;
};
file main.cpp to exercise a and b:
#include <iostream>
#include <map>
#include "a.hpp"
#include "b.hpp"
int main() {
// approach using static map within class
a obj1;
a obj2;
a obj3;
a obj4;
a* fnd = a::Find(2);
std::cout << "object with id 2 " << (fnd ? "" : "not ") << "found\n";
// application level map
std::map<unsigned, b*> id2b_map;
unsigned id = 0;
b obj5(++id);
id2b_map.insert(id2b_map.end(), std::make_pair<unsigned, b*>(id, &obj5));
b obj6(++id);
id2b_map.insert(id2b_map.end(), std::make_pair<unsigned, b*>(id, &obj6));
b obj7(++id);
id2b_map.insert(id2b_map.end(), std::make_pair<unsigned, b*>(id, &obj7));
b obj8(++id);
id2b_map.insert(id2b_map.end(), std::make_pair<unsigned, b*>(id, &obj8));
std::map<unsigned, b*>::iterator i = id2b_map.find(2);
std::cout << "object with id 2 " << (i == id2b_map.end() ? "not " : "") << "found\n";
return 0;
}
I can see that the static member collection idea is more convenient for the user of a.
It is not more convenient, except for simple cases. Adding a static map of instances means you add a hidden dependency. Are there any use cases when you do not need this list? If you place it as a static private instance, you will always have it there (whether you use it or not).
Also, the code you wrote, will have unexpected results here:
class a::id2a_map : public std::map<int, a*>
std::map is not written to be inherited, which means it doesn't have a virtual destructor. When the class gets destroyed, it's destructor may not get called (compiler-dependent).
Are there other alternatives which should also be considered similar? What are the pros and cons of a and b approach?
B approach is better, but not as good as it could be. The implementation will not depend on std::list (minimizing dependencies is always a plus) but the list has pointers, and it shouldn't.
Could you write something like this instead?
class a {
public:
a();
~a();
unsigned m_id; // same as in your example
};
client code:
std::map<unsigned, a> instances; // not static; if you need it somewhere else,
// just pass it in as a parameter
a instance;
instances[a.m_id] = std::move(a);
// use instances.find from here on
The code is straight-foward, minimal and doesn't break SRP.
In the case of static members, if you have static methods doing something with them, since the compiler knows all about what the methods will do at compile time, it has a better chance to optimize them well. Depending on the compiler, the amount of optimization varies.
This is an interesting thread of discussion:
http://bytes.com/topic/c/answers/617238-static-functions-better-optimized-compilers