[多态]用输入的名字来生成子类的对象
第一次写多态的程序,遇到一个问题,就是输入一个类名字,怎样方便地 new 出一个子类的对象。
假设基类是 base,子类有 A,B。
开始我是这样的:
if (name == base::class_name())
p = new base;
else if (name == A::class_name())
p = new A;
else if (name == B::class_name())
p = new B;
else
p = 0;
我觉得这样不好,不容易维护,想添加新的子类的话,要改的地方很多,而且容易漏掉。
于是我就想有一个“管理器”来给我管理就好了,我只要在最开始的时候向管理器注册一下,以后用名字就可以方便地从管理器里分配一个新的对象了。
初步想的话,每个类应该有两个 static 成员函数,一个用来给出类的名字,另一个则用于分配一个对象。
可以写出基类如下:
class base
{
public:
~base ();
static const char* class_name ()
{
static const char _name[]="base";
return _name;
}
static base* alloc () { return new base; }
};
这样,每个类都有一对 class_name 和 alloc,查到 class_name 后就可以通过 alloc 分配一个对象。
下面是管理器的代码:
template <class base_t>
class poly_alloc
{
typedef base_t* value_type;
typedef value_type (*alloc_type)();
vector<pair<const char*, alloc_type> > alloces;
public:
void
reg (const char* name, alloc_type a)
{
alloces.push_back (make_pair (name, a));
}
value_type
alloc (const string& name)
{
value_type _new = 0;
for (int i = 0; i < alloces.size(); i++)
if (name == alloces[i].first)
{
_new = (*alloces[i].second)();
break;
}
return _new;
}
};
用 reg 去注册一个子类(当然也可以是基类),以后用 alloc 就可以分配了。如:
poly_alloc<mybase> pa;
pa.reg (mybase::class_name(), mybase::alloc);
pa.reg (A::class_name(), A::alloc);
pa.reg (B::class_name(), B::alloc);
mybase* p;
p = pa.alloc ("A");
delete p;
整个代码如下:
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
#include <utility>
using namespace std;
class mybase
{
public:
virtual ~mybase ()
{}
static mybase*
alloc ()
{
mybase* _new = new mybase;
return _new;
}
virtual const char*
name ()
{
return class_name();
}
static const char*
class_name ()
{
static const char _name[]="base";
return _name;
}
virtual void
foo ()
{
cout << name() << " done" << endl;
}
};
class A: public mybase
{
public:
static mybase*
alloc ()
{
A* _new = new A;
return _new;
}
const char*
name ()
{
return class_name();
}
static const char*
class_name ()
{
static const char _name[]="A";
return _name;
}
void
foo ()
{
cout << name() << " done" << endl;
}
};
class B: public mybase
{
public:
static mybase*
alloc ()
{
B* _new = new B;
return _new;
}
const char*
name ()
{
return class_name();
}
static const char*
class_name ()
{
static const char _name[]="B";
return _name;
}
void
foo ()
{
cout << name() << " done" << endl;
}
};
template <class base_t>
class poly_alloc
{
typedef base_t* value_type;
typedef value_type (*alloc_type)();
vector<pair<const char*, alloc_type> > alloces;
public:
void
reg (const char* name, alloc_type a)
{
alloces.push_back (make_pair (name, a));
}
value_type
alloc (const string& name)
{
value_type _new = 0;
for (int i = 0; i < alloces.size(); i++)
if (name == alloces[i].first)
{
_new = (*alloces[i].second)();
break;
}
return _new;
}
};
int
main ()
{
poly_alloc<mybase> pa;
pa.reg (mybase::class_name(), mybase::alloc);
pa.reg (A::class_name(), A::alloc);
pa.reg (B::class_name(), B::alloc);
mybase* p;
cout << "There are class (base, A, B)" << endl;
string str;
do
{
cout << "Please input a class name:";
cin >> str;
p = pa.alloc (str);
if (p == 0)
break;
p->foo ();
delete p;
}
while (true);
system ("Pause");
return 0;
}
假设基类是 base,子类有 A,B。
开始我是这样的:
if (name == base::class_name())
p = new base;
else if (name == A::class_name())
p = new A;
else if (name == B::class_name())
p = new B;
else
p = 0;
我觉得这样不好,不容易维护,想添加新的子类的话,要改的地方很多,而且容易漏掉。
于是我就想有一个“管理器”来给我管理就好了,我只要在最开始的时候向管理器注册一下,以后用名字就可以方便地从管理器里分配一个新的对象了。
初步想的话,每个类应该有两个 static 成员函数,一个用来给出类的名字,另一个则用于分配一个对象。
可以写出基类如下:
class base
{
public:
~base ();
static const char* class_name ()
{
static const char _name[]="base";
return _name;
}
static base* alloc () { return new base; }
};
这样,每个类都有一对 class_name 和 alloc,查到 class_name 后就可以通过 alloc 分配一个对象。
下面是管理器的代码:
template <class base_t>
class poly_alloc
{
typedef base_t* value_type;
typedef value_type (*alloc_type)();
vector<pair<const char*, alloc_type> > alloces;
public:
void
reg (const char* name, alloc_type a)
{
alloces.push_back (make_pair (name, a));
}
value_type
alloc (const string& name)
{
value_type _new = 0;
for (int i = 0; i < alloces.size(); i++)
if (name == alloces[i].first)
{
_new = (*alloces[i].second)();
break;
}
return _new;
}
};
用 reg 去注册一个子类(当然也可以是基类),以后用 alloc 就可以分配了。如:
poly_alloc<mybase> pa;
pa.reg (mybase::class_name(), mybase::alloc);
pa.reg (A::class_name(), A::alloc);
pa.reg (B::class_name(), B::alloc);
mybase* p;
p = pa.alloc ("A");
delete p;
整个代码如下:
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
#include <utility>
using namespace std;
class mybase
{
public:
virtual ~mybase ()
{}
static mybase*
alloc ()
{
mybase* _new = new mybase;
return _new;
}
virtual const char*
name ()
{
return class_name();
}
static const char*
class_name ()
{
static const char _name[]="base";
return _name;
}
virtual void
foo ()
{
cout << name() << " done" << endl;
}
};
class A: public mybase
{
public:
static mybase*
alloc ()
{
A* _new = new A;
return _new;
}
const char*
name ()
{
return class_name();
}
static const char*
class_name ()
{
static const char _name[]="A";
return _name;
}
void
foo ()
{
cout << name() << " done" << endl;
}
};
class B: public mybase
{
public:
static mybase*
alloc ()
{
B* _new = new B;
return _new;
}
const char*
name ()
{
return class_name();
}
static const char*
class_name ()
{
static const char _name[]="B";
return _name;
}
void
foo ()
{
cout << name() << " done" << endl;
}
};
template <class base_t>
class poly_alloc
{
typedef base_t* value_type;
typedef value_type (*alloc_type)();
vector<pair<const char*, alloc_type> > alloces;
public:
void
reg (const char* name, alloc_type a)
{
alloces.push_back (make_pair (name, a));
}
value_type
alloc (const string& name)
{
value_type _new = 0;
for (int i = 0; i < alloces.size(); i++)
if (name == alloces[i].first)
{
_new = (*alloces[i].second)();
break;
}
return _new;
}
};
int
main ()
{
poly_alloc<mybase> pa;
pa.reg (mybase::class_name(), mybase::alloc);
pa.reg (A::class_name(), A::alloc);
pa.reg (B::class_name(), B::alloc);
mybase* p;
cout << "There are class (base, A, B)" << endl;
string str;
do
{
cout << "Please input a class name:";
cin >> str;
p = pa.alloc (str);
if (p == 0)
break;
p->foo ();
delete p;
}
while (true);
system ("Pause");
return 0;
}
...全文
相关推荐
java面向对象编程猜一猜游戏.zip
用java写的项目,项目可以直接运行,请放心下载使用。
Java多态的实现机制
Java多态的实现机制,多态是java的三大属性之一,开发中很重要的一个环节
浅谈将子类对象赋值给父类对象
最近对将子类对象赋值给父类对象有点心得,想和大家分享一下.但本人水平有限,请各位指正和批评. 言归正传,下面是几个小例子,请大家看一看. 测试一 父类: public class Supclass { public void print() { System.out.println(“this
babynamer:简单的Python程序,用于基于给定年份的最受欢迎名称来生成婴儿名字
婴儿名字 由Randall Arms用Python编写@ randallarms.com 概括 根据一年中最流行的名字生成很棒的婴儿创意名字。 指示 输入年份(当前选项:1941-2019),性别(男孩,女孩)和中间名选项(是,否)。
进一步理解Java中的多态概念
主要介绍了进一步理解Java中的多态概念,是Java入门学习中的基础知识,需要的朋友可以参考下



