您的位置:首页 > 编程语言 > C语言/C++

[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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐