[C++学习笔记14]动态创建对象(定义静态方法实现在map查找具体类名对应的创建函数,并返回函数指针,map真是一个万能类)good
2017-12-04 01:08
2126 查看
[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)
http://www.cnblogs.com/ifpelset/articles/4544750.html
相关文章推荐
- C++函数返回一个对象学习笔记
- C++学习笔记(13)——利用对象、引用、指针调用虚函数
- C++ 利用指针和结构体实现一个函数返回多个值
- 【c++总结-类】一个例子知道类的创建,对象,函数实现,构造函数,析构函数
- C++学习14:使用typedef定义函数指针类型
- Greenplum+Hadoop学习笔记-14-定义数据库对象之创建与管理模式
- C++ 学习笔记(14)重载运算与类型转换、函数对象、function库
- 学习笔记之14-返回指针的函数与指向函数的指针
- C++实现反射(根据类名动态创建对象)
- effective C++笔记之条款31、32: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针所指对象的引用、尽可能地推迟变量的定义
- C++ 学习笔记(6)函数、局部静态对象、重载函数、内联函数、constexpr函数、调试帮助、函数匹配、函数指针
- C++:对象数组、对象动态申请和释放、类的定义和实现分开、this指针、常成员函数、时钟
- C++学习笔记(八):函数重载、函数指针和函数对象
- JS学习笔记1——不要使用JavaScript内置的parseInt()和Number()函数,利用map和reduce操作实现一个string2int()函数
- 【C++】【学习笔记】【未成功实现】关于指针的函数【very difficult】
- 学习笔记之C++为什么将函数声明或者类的定义放在.h文件中,而将其实现放在原文件中
- Effective C++学习笔记:必须返回一个对象时不要试图返回一个引用
- 【学习笔记六】 - js中 创建对象的模式与继承 及 js中实现块级作用域和函数私有变量 《js高程》6-7笔记
- C语言学习9: malloc动态内存存储,动态内存分配去空格字符增长版,动态内存分配去符号incr增长版,型参和返回值都是int型的函数的指针,main函数的地址也可以用指针指向,typedef定义函数指针,函数定义与嵌套的作用,返回函数指针类型,const作用
- 《面向对象基础:C++实现》学习笔记之五