How to create an array of classes in C ++?

the code:

struct Base { ... }; struct A : public Base { ... }; struct B : public Base { ... }; struct C : public Base { ... }; 

Is it possible to create an array containing these types of struct? sample / expected result:

 Type inheritedTypesOfStruct[3] = {A, B, C}; 

The purpose of this is that later I want to create an object with a random class retrieved from the array.

+6
source share
5 answers
 #include <cstdlib> #include <ctime> #include <iostream> #include <map> #include <vector> #include <memory> using namespace std; // interface class Base { public: virtual ~Base() { } virtual int getClassId() = 0; }; // class A relizes interface Base, has ID == 1 (is used in automatic registration to factory) class A : public Base { public: const static int ID = 1; static Base* CreateInstance() { return new A(); } virtual int getClassId() { return ID; } virtual ~A() { } }; // class B relizes interface Base, has ID == 2 (is used in automatic registration to factory) class B : public Base { public: const static int ID = 2; static Base* CreateInstance() { return new B(); } virtual int getClassId() { return ID; } virtual ~B() { } }; // this is the objects factory, with registration only (unregister s not allowed) class ObjectFactory { ObjectFactory() { } ObjectFactory(ObjectFactory&) { } public: virtual ~ObjectFactory() { } static ObjectFactory& instance() { static ObjectFactory objectFactory; return objectFactory; } typedef Base* (*Creator) (); void registerCreator(int id, Creator creator) { registry[id] = creator; } Base* CreateById(int id) { return registry[id](); } private: map<int, Creator> registry; }; // this template class is used for automatic registration of object creators template <class T> struct RegisterToFactory { RegisterToFactory(ObjectFactory& factory) { factory.registerCreator(T::ID, &T::CreateInstance); } }; namespace { // automaticaly register creators for each class RegisterToFactory<A> autoregisterACreator(ObjectFactory::instance()); RegisterToFactory<B> autoregisterBCreator(ObjectFactory::instance()); } // lets this this solution int main(int argc, char *argv[]) { vector<int> ids; ids.push_back(static_cast<int>(A::ID)); ids.push_back(static_cast<int>(B::ID)); srand(time(0)); for (int i = 0; i < 20; ++i) { int randomClasssId = ids[rand() % ids.size()]; auto_ptr<Base> testObject(ObjectFactory::instance().CreateById(randomClasssId)); cout << "Object of classId = " << testObject->getClassId() << " has been produced by factory." << endl; } system("PAUSE"); return EXIT_SUCCESS; } 
+1
source

If your compiler supports RTTI , you can do something like:

 const type_info *inheritedTypesOfStruct[3] = { &typeid(A), &typeid(B), &typeid(C) }; 

However, you cannot instantiate the class using only type_info . factory pattern may be the best answer to your root problem.

Update: since type_info instances cannot be copied (their copy constructor and assignment operator private ), and the link arrays are illegal, constant pointers should be used in the above example.

+5
source

You can create an array of functions, each of which returns a base pointer (or smart pointer), each of which points to objects of your various derived classes. eg.

 typedef std::unique_ptr<Base> base_ptr; template<typename Derived> base_ptr CreateObject() { return base_ptr(new Derived); } int main() { std::function<base_ptr(void)> f[3] = { CreateObject<A>, CreateObject<B>, CreateObject<C> }; base_ptr arr[10]; for (int i=0; i<10; ++i) arr[i] = f[rand()%3](); } 

Here it is in action: http://ideone.com/dg4uq

+5
source

My question does not arise. Are you requesting an array that can contain different types of instances at the same time? This is possible using polymorphism, of course. Or are you trying to get an array of types (e.g. reflection)? This would be possible using information such as RTTI or Qt (as an example), but I never did.

0
source

You can look here: http://www.java2s.com/Code/Cpp/Class/Objectarraypolymorphism.htm

on how to use polymorphism in C ++.

-1
source

Source: https://habr.com/ru/post/904917/


All Articles