C++ dynamically creates and constructs derived classes

Method 1: If your class names have a uniform prefix, such as C, C1, C2, C3, you can use macros to create them 

class C
{
public :
	virtual void run() = 0;
};

class C1 : public C
{
public :
	void run() { printf("C1 run\r\n"); }
};

class C2 : public C
{
public :
	void run() { printf("C2 run\r\n"); }
};

#define NEW_C_INSTANCE(class_id) new C##class_id();

int main()
{
	//int id = 2; //不可以这样
	//C* c = NEW_C_INSTANCE(id);
	
	//C* c = NEW_C_INSTANCE(1);
	C* c = NEW_C_INSTANCE(2);
	
	c->run();
	getchar();
	return 0;
}


Advantages: The type is determined during the compile time, and the code is efficient.
Disadvantages: Need to have a unified naming prefix.
      The parameters of NEW_C_INSTANCE cannot be assigned externally, only fixed codes can be written.
      Relevant header files need to be defined in advance, which is less flexible.


Method 2: Use static function pointer to create


class S;

typedef S* (*s_creator_function)(); 

class S
{
public:
	static S* create(){	return NULL;}
	virtual void run() = 0;
};

class S1 : public S
{
public:
	static S* create(){ return new S1();}
	void run() {printf("S1 run!\r\n");}
};

class S2 : public S
{
public:
	static S* create(){	return new S2();}
	void run() {printf("S2 run!\r\n");}
};

class S_Factory
{
public:
	void registerCreator(int id, s_creator_function func )
	{
		map.insert( std::pair<int,s_creator_function>(id, func) );
	}

	S* create(int id)
	{
		std::map<int, s_creator_function>::iterator it;  
		it = map.find(id);//在map中查找创建函数
		if( it != map.end() )
			return (it->second)();
		return NULL;
	}

private:
	std::map<int, s_creator_function> map;
};

S_Factory sFactory;

int main()
{
	sFactory.registerCreator(1, S1::create);
	sFactory.registerCreator(2, S2::create);

	//int n = 1;
	int n = 2;
	S* s = sFactory.create(n);
	s->run();

	getchar();
	return 0;

}

Advantages: flexible expansion.
Disadvantages: Slightly complicated when creating. The rules and management are not good, and it is hard to check when something goes wrong.

Guess you like

Origin blog.csdn.net/RoadToTheExpert/article/details/8939105