[C++学习笔记14]动态创建对象
- C#/Java中的反射机制
动态获取类型信息(方法与属性)
动态创建对象
动态调用对象的方法
动态操作对象的属性
前提:需要给每个类添加元数据 - 动态创建对象
实现原理:通过定义一个宏REGISTER_CLASS,传入类名,在该宏中创建一个类独有的Register类,类中定义静态方法创建对象(new)并返回指针,并在该类中定义一个公共Register类的成员变量,在该公共Register类的构造函数中调用工厂类的Register方法注册类名与创建对象的函数指针到map,在工厂类中定义静态方法实现在map查找具体类名对应的创建函数,并返回调用即可。
具体实现代码
#ifndef __DYN_BASE_H__ #define __DYN_BASE_H__ #include <map> #include <string> using namespace std; typedef void* (*CREATE_FUNC)(); class DynObjectFactory { public: static void *createObject(const string &name) { map<string, CREATE_FUNC>::const_iterator it; it = mapCls_.find(name); if (it == mapCls_.end()) return nullptr; return it->second(); } static void Register(const string &name, CREATE_FUNC func) { mapCls_[name] = func; } private: static map<string, CREATE_FUNC> mapCls_; }; // g++ // __attribute ((weak)) __declspec(selectany) map<string, CREATE_FUNC> DynObjectFactory::mapCls_; class Register { public: Register(const string &name, CREATE_FUNC func) { DynObjectFactory::Register(name, func); } }; #define REGISTER_CLASS(class_name) \ class class_name##Register{ \ public: \ static void* newInstance() \ { \ return new class_name; \ } \ private: \ static Register reg_; \ }; \ Register class_name##Register::reg_(#class_name, class_name##Register::newInstance); #endif // __DYN_BASE_H__
#ifndef __SHAPE_H__ #define __SHAPE_H__ #include <iostream> #include <vector> #include <string> using namespace std; class Shape { public: virtual void Draw() = 0; virtual ~Shape() {} }; class Circle : public Shape { public: void Draw(); ~Circle(); }; class Rectangle : public Shape { public: void Draw(); ~Rectangle(); }; class Square : public Shape { public: void Draw(); ~Square(); }; #endif // __SHAPE_H__
#include "Shape.h" #include "DynBase.h" void drawAllShapes(const vector<Shape *> v) { vector<Shape *>::const_iterator it; for (it = v.begin(); it != v.end(); ++it) { (*it)->Draw(); } } void deleteAllShapes(const vector<Shape *> v) { vector<Shape *>::const_iterator it; for (it = v.begin(); it != v.end(); ++it) { delete (*it); } } int main(void) { //Shape s; // Error, 抽象类不能实例化对象 vector<Shape *> v; Shape *ps = NULL; ps = static_cast<Shape *>(DynObjectFactory::createObject("Circle")); v.push_back(ps); ps = static_cast<Shape *>(DynObjectFactory::createObject("Square")); v.push_back(ps); ps = static_cast<Shape *>(DynObjectFactory::createObject("Rectangle")); v.push_back(ps); drawAllShapes(v); deleteAllShapes(v); // 未将Shape基类的析构函数声明为虚函数之前,并不会调用各个派生类的析构函数 // 声明为虚函数之后,就会调用了 return 0; }
#include "Shape.h" #include "DynBase.h" void Circle::Draw() { cout << "Circle Draw ... " << endl; } Circle::~Circle() { cout << "~Circle ... " << endl; } void Rectangle::Draw() { cout << "Rectangle Draw .." << endl; } Rectangle::~Rectangle() { cout << "~Rectangle ... " << endl; } void Square::Draw() { cout << "Square Draw ..." << endl; } Square::~Square() { cout << "~Square ... " << endl; } REGISTER_CLASS(Circle) REGISTER_CLASS(Square) REGISTER_CLASS(Rectangle)