派生类的自动创建问题??

fishboyzyf 2008-10-22 09:04:50
我现在建立一个类CFilyChartUnit做为基类,配成出CFilyCombineUnit1,CFilyCombineUnit2,CFilyCombineUnit3三个类
在CFilyChartUnit有这个成员变量m_ChartType,在
CFilyChartUnit中m_ChartType为0
CFilyCombineUnit1中m_ChartType为1
CFilyCombineUnit2中m_ChartType为2
CFilyCombineUnit3中m_ChartType为3
当m_ChartType为1时,我想实例化CFilyCombineUnit1类结构
当m_ChartType为2时,我想实例化CFilyCombineUnit2类结构
当m_ChartType为3时,我想实例化CFilyCombineUnit3类结构
我现在不行用这种方式
CFilyChartUnit * CFilyChartUnit::GetChartUnit(int m_ChartType)

switch(m_ChartType)

case 0:
return new CFilyChartUnit();
case 1:
return new CFilyCombineUnit1();
case 2:
return new CFilyCombineUnit2();
.....


我想实现CFilyChartUnit chart = new CFilyChartUnit(m_ChartType)这种方式
实例化,如果m_ChartType为1返回CFilyCombineUnit1类结构,如果m_ChartType为2返回CFilyCombineUnit2类结构
高手们有没有好的方法实现?
...全文
206 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
pelasido 2008-10-23
  • 打赏
  • 举报
回复
CFilyChartUnit* file_char_unit = file_chart_unit_factory::create_object(1);
seaboat_wang 2008-10-22
  • 打赏
  • 举报
回复
顶5楼。。。。。。。



想了半天以后,看了5楼,豁然开朗。。。

复习了复习了。。。
yshuise 2008-10-22
  • 打赏
  • 举报
回复
凡是用switch的都是没有看过《设计模式》,不懂什么叫面向对象。
编程-鸟人-_-- 2008-10-22
  • 打赏
  • 举报
回复
同意5楼
once_and_again 2008-10-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 fishboyzyf 的回复:]
如果不使用
switch(nChartType)

case 0:
return new CFilyChartUnit();
case 1:
return new CFilyCombineUnit1();
case 2:
return new CFilyCombineUnit2();
default:
}
没有好的解决办法?
[/Quote]如果有switch ,case的地方,很冗肿,
基本上是设计有问题。
迷途的书童 2008-10-22
  • 打赏
  • 举报
回复
学习。。。
OenAuth.Core 2008-10-22
  • 打赏
  • 举报
回复
UP五楼,LZ这种想法,基本就是抽像基类出现的原因,呵呵
xxgamexx 2008-10-22
  • 打赏
  • 举报
回复
5楼的好点,也省了静态函数!

结构也挺清晰的,学习了!
帅得不敢出门 2008-10-22
  • 打赏
  • 举报
回复
同意5楼.
chenzhp 2008-10-22
  • 打赏
  • 举报
回复
我觉得最好是改成抽象类,通过抽象基类指针来实现实例化各个派生类

class CAbstrctUnit
{
protected:
int m_ChartType;
public:
int virtual returnValue() = 0;

};
class CFilyChartUnit:public CAbstrctUnit
{
public:
CFilyChartUnit(){};
int returnValue(){m_ChartType = 0;return m_ChartType; }
};
class CFilyChartUnit1:public CAbstrctUnit
{
public:
CFilyChartUnit1(){};
int returnValue(){m_ChartType = 1;return m_ChartType;}
};
class CFilyChartUnit2:public CAbstrctUnit
{
public:
CFilyChartUnit2(){};
int returnValue(){m_ChartType = 2;return m_ChartType;}
};
CAbstrctUnit* returnType(int m_value)//最后返回的都是基类指针,然后根据多态性,动态绑定到各个派生类上
{
switch(m_value)
{
case 0:
return new CFilyChartUnit();//返回Unit
case 1:
return new CFilyChartUnit1();//返回Unit1
case 2:
return new CFilyChartUnit2();//返回Unit2
break;
}
}
void main()
{
CAbstrctUnit* FilyChartUnit = returnType(2);
int a = FilyChartUnit->returnValue();//测试打印出来的值
printf("%d\n",a);
}
muturenby 2008-10-22
  • 打赏
  • 举报
回复
我觉得你想的就不对!
CFilyChartUnit中m_ChartType为0 可以的!
但是在派生类中1、2、3中,这三个派生类都没还有实例化,里面的成员变量是不会有值的!
你怎么会想成:

CFilyChartUnit中m_ChartType为0
CFilyCombineUnit1中m_ChartType为1
CFilyCombineUnit2中m_ChartType为2
CFilyCombineUnit3中m_ChartType为3
当m_ChartType为1时,我想实例化CFilyCombineUnit1类结构
当m_ChartType为2时,我想实例化CFilyCombineUnit2类结构
当m_ChartType为3时,我想实例化CFilyCombineUnit3类结构

呢?
再用switch(m_ChartType){}肯定就不对了!
shada 2008-10-22
  • 打赏
  • 举报
回复
注意,函数声明写错了,应该这样:
static CFilyChartUnit* CFilyChartUnit:CreateClass(int nChartType)
{


...
}
fishboyzyf 2008-10-22
  • 打赏
  • 举报
回复
如果不使用
switch(nChartType)

case 0:
return new CFilyChartUnit();
case 1:
return new CFilyCombineUnit1();
case 2:
return new CFilyCombineUnit2();
default:
}
没有好的解决办法?
shada 2008-10-22
  • 打赏
  • 举报
回复
你应该在基类中定义一个CreateClass成员函数且必须是静态的。
比如:
static CFilyChartUnit:CreateClass(int nChartType)
{
switch(nChartType)

case 0:
return new CFilyChartUnit();
case 1:
return new CFilyCombineUnit1();
case 2:
return new CFilyCombineUnit2();
default:
}
}

实际用的时候:
CFilyChartUnit chart = CFilyChartUnit::CreateClass(0);//注意调用静态函数不需要new
moolleychean 2008-10-22
  • 打赏
  • 举报
回复
基本思路如下:泛型+工厂方法模式

//泛型工厂
template<typename Product, //你的产品簇的基类
typename Identifier, //产品的识别类型,如int
typename Creator> //产品的创建方法
class base_factory
{
public:
static bool register(const Identifier & id, Creator creator)
{
return s_product_list.insert(std::map<Identifier, Creator>::value_type(id, creator)).second;
}

static bool unregister(const Identifier & id)
{
return (s_product_list.erase(id) == 1);
}

T * create_object(const Identifier & id)
{
std::map<Identifier, Creator>::const_iterator it = s_product_list.find(id);
if (it != s_product_list.end())
{
return (id->second)();
}
return 0;
}
private:

static std::map<Identifier, Creator> s_product_list;
}

//具体工厂
typedef base_factory<CFilyChartUnit, int, CFilyChartUnit * (*)()> file_chart_unit_factory


//产品基类
class CFilyChartUnit
{
protected:
int m_ChartType;

};

//产品1
class CFilyCombineUnit1;

CFilyChartUnit * create1()
{
return new CFilyCombineUnit1;
}

const int k_chart_type1 = 1;

const bool k_registed1 = file_chart_unit_factory::register(k_chart_type1, create1);

class CFilyCombineUnit1:public CFilyChartUnit
{
public:


};

//产品2
class CFilyCombineUnit2;

CFilyChartUnit * create2()
{
return new CFilyCombineUnit2;
}

const int k_chart_type2 = 2;

const bool k_registed2 = file_chart_unit_factory::register(k_char_type2, create2);

class CFilyCombineUnit2:public CFilyChartUnit
{
public:

};

//产品3

class CFilyCombineUnit3;

CFilyChartUnit * create3()
{
return new CFilyCombineUnit3;
}

const int k_chart_type3 = 3;

const bool k_registed3 = file_chart_unit_factory::register(char_type, create3);

class CFilyCombineUnit3:public CFilyChartUnit
{
public:

};

//更多的产品,依葫芦画瓢
......

//使用
int main()
{
CFilyChartUnit* file_char_unit = file_chart_unit_factory::create_object(1);
if (file_char_unit != 0)
{
//多态调用
}
return 0;
}
yshuise 2008-10-22
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 chenzhp 的回复:]
引用 12 楼 yshuise 的回复:
凡是用switch的都是没有看过《设计模式》,不懂什么叫面向对象。


太绝对了吧?
[/Quote]抱歉。嘿嘿。
chenzhp 2008-10-22
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 yshuise 的回复:]
凡是用switch的都是没有看过《设计模式》,不懂什么叫面向对象。
[/Quote]

太绝对了吧?
yshuise 2008-10-22
  • 打赏
  • 举报
回复
对 factory模式 16楼
jackzhhuang 2008-10-22
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 once_and_again 的回复:]
引用 2 楼 fishboyzyf 的回复:
如果不使用
switch(nChartType)

case 0:
return new CFilyChartUnit();
case 1:
return new CFilyCombineUnit1();
case 2:
return new CFilyCombineUnit2();
default:
}
没有好的解决办法?
如果有switch ,case的地方,很冗肿,
基本上是设计有问题。
[/Quote]

我同意10、12楼。

应该再封装一个类,作为生成子类的决策者,然后其子类各生成对应的对象,这样用户只要调用这个类相应的函数就可以获得相应对象。

这样如果需要生成的类很多,数据就不会都集中到一个factory类上,而是分散到strategy的子类上,耦合度大大降低

这就是factory——strategy模式。
yshuise 2008-10-22
  • 打赏
  • 举报
回复
class CAbstrctUnit
{

public:
int virtual returnValue() = 0;
~virtual CAbstrctUnit(){}

};
class CFilyChartUnit:public CAbstrctUnit
{

public:
int returnValue(){m_ChartType = 0;return m_ChartType; }

private:
int m_ChartType;

};
class CFilyChartUnit1:public CAbstrctUnit
{

public:
CFilyChartUnit1(){};
int returnValue(){m_ChartType = 1;return m_ChartType;}
private:
int m_ChartType;
};
class CFilyChartUnit2:public CAbstrctUnit
{

public:
CFilyChartUnit2(){};
int returnValue(){m_ChartType = 2;return m_ChartType;}
private:
int m_ChartType;
};

class Factory{
public:
CAbstrctUnit* createCFilyChartUnit(){new CFilyChartUnit;}
CAbstrctUnit* createCFilyChartUnit1(){new CFilyChartUnit1;}
CAbstrctUnit* createCFilyChartUnit2(){new CFilyChartUnit2;}

};
加载更多回复(2)

64,644

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧