C++反射和JavaScript实现

据说,C#和Java有根据类名(字符串)直接创建类对象的语法,而C++没有。C++的解决方案是什么呢?当然可以通过switch-case或if-else分支实现,看过《重构》的同学都知道,这是“坏味道”的代码。

MFC中有个“动态创建”的技术,一般是按这个思路去实现,只不过不会使用宏。思路是这样的:先登记,即将类名与创建对象的方法建立一对一的关系,通常是保存在一个map中,key是类名,value是创建对象的方法。

看一个C++的例子,参考这篇文章

//test.h
#pragma once

#include <iostream>

class Test
{
public:
	Test()
	{
		std::cout << "call Test Constructor fun" << std::endl;
	}

	~Test()
	{
		std::cout << "call Test Destructor fun" << std::endl;
	}

	void print()
	{
		std::cout << "call Test print fun" << std::endl;
	}
};

void* create_Test()
{
	Test* t = new Test;
	return (t == NULL) ? NULL : t;
}
//class_factory.h
#pragma once

#include <iostream>
#include <string>
#include <map>

typedef void* (*create_fun)();

class ClassFactory
{
private:
	ClassFactory() {};
	std::map<std::string, create_fun> my_map;
public:
	~ClassFactory() {};
	//根据类名创建对象
	void* getClassByName(std::string name)
	{
		std::map<std::string, create_fun>::iterator it = my_map.find(name);
		if (it == my_map.end())
		{
			return NULL;//没有找到类名
		}
		create_fun fun = it->second;
		if (!fun)
		{
			return NULL;
		}
		return fun();//执行函数并返回函数执行的结果
	}

	//登记类名与函数指针的对应关系
	void registClass(std::string name, create_fun fun)
	{
		my_map[name] = fun;
	}

	//单例
	static ClassFactory& getInstance()
	{
		static ClassFactory fac;
		return fac;
	}
};
//main.cpp
#include "test.h"
#include "class_factory.h"

int main()
{
	//登记
	ClassFactory::getInstance().registClass("Test", create_Test);

	//获取类对象
	Test* t = (Test*)ClassFactory::getInstance().getClassByName("Test");
	if (!t)
	{
		std::cout << "get instance Test err;" << std::endl;
		return 1;
	}

	t->print();
	delete t;
	return 0;
}

由上面的代码,再仔细看一下注册的value是什么?是create_Test,执行创建对象的函数。其实创建对象需要“构造函数”就可以了,用JavaScript改写一下上面的代码,如下:

// test.js
const { MClass_factory } = require('./class_factory');

class MTest
{
    constructor() {
        console.log("call MTest Constructor fun");
    }

    print() {
        console.log("call MTest print fun");
    }
}

MClass_factory.getInstance().registClass("MTest", MTest);
module.exports.MTest = MTest;
// class_factory.js
class MClass_factory {
    constructor() {
        this.classReg = [];
    }

    getClassByName(constructorName) {
        for (let item of this.classReg) {
            if (item['name'] === constructorName) {
                let constructorFun = item['createFun'];
                let obj = new constructorFun;
                return obj;
            }
        }
        return;
    }

    registClass(name, createFun) {
        this.classReg.push({ 'name': name, 'createFun': createFun });
    }

    static getInstance() {
        if (!this.instance) {
            this.instance = new MClass_factory();
        }
        return this.instance;
    }
}

module.exports.MClass_factory = MClass_factory;
// main.js
const { MClass_factory } = require('./class_factory');
const { MTest } = require('./test');
let objTest = MClass_factory.getInstance().getClassByName('MTest');
objTest.print();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值