设计高手来帮忙呀!

时间:2022-08-28 16:41:45
struct _A{...};
struct _B{...};
//===========================

class X{
 public:
   virtual void Action()=0;
};

class A :public X{
  public:
    virtual void Action(){...};
    vector<_A>   V_A;
  public:
    vector<_A>&  getData(){...return this->V_A;}
};

class B :public X{
 public:
   virtual void Action(){...};
   vector<_B>   V_B;
 public:
    vector<_B>&  getData(){...return this->V_B;}
};
//=====================================================

问题是:
   X*  pX;    
   A    a;...
   pX=&a;   
..............
..............
  过了一段时间我要获得a的数据:
则我必须向下转换!
  A*  pA=dynamic_cast<A*>(pX);
其实我真的不想向下转换!
  
这样我必须这样作!
class X{
 public:
   virtual void Action()=0;
    virtual vector<_A>&  getData(){...}//添加新的虚函数
};
  //派生类相映的函数前面要加上virtual:
class A :public X{
  public:
    virtual void Action(){...};
    vector<_A>   V_A;
  public:
    virtual vector<_A>&  getData(){...return this->V_A;}
};


同样我要获得B的 getData(){...return this->V_B;}
这样又要在class X{....
    virtual vector<_B>&  getData(){...}//添加新的虚函数
};
等不断的进行重载虚函数!将相映的派生类的函数前加virtual;

假如以后我有要添加派生类!
且又要获得派生类的数据这样将
  不断的进行重载虚函数!将相映的派生类的函数前加virtual

最后基类回扩充的非常非常臃肿!

有没有什么更好的办法呢?




17 个解决方案

#1


问题是:
  X*  pX;   
  A    a;...
  pX=&a; 
..............
..............
  过了一段时间我要获得a的数据:
则我必须向下转换!
  A*  pA=dynamic_cast <A*>(pX);
其实我真的不想向下转换!
  ================你没用new对象,你好意思只是把栈对象的地址付给pX

#2


类是用来描述一类事物的抽象。

而你的做法是让这个类中有一个新物种,然后又重新修改该抽象,破坏了抽象描述的定义。

当你需要新的行为的时候,你应该考虑新的行为的抽象与原有行为抽象的联系。

比如你可以为后来新的行为定义某种接口
例如:

原有抽象:
class 动物
{
public:
   virtual  void 叫()=0;
}

class 猫:public 动物
{
virtual  void 叫();
}

新事物:

class 机器猫:public 猫,机器
{
....
}

定义新行为抽象

class 机器
{
virtual void 充电();
}

这样比较好的意义和使用方式来构件新类别。

建议有空看看 ,*的设计模式。

#3


你获得a的数据,干嘛非得跟X扯上关系呢?你直接用A new一个对象不就行了

#4


UP

#5


看看常用的设计模式,应该有符合你要求的

#6


引用楼主的话:
假如以后我有要添加派生类! 
且又要获得派生类的数据这样将 
  不断的进行重载虚函数!将相映的派生类的函数前加virtual 

最后基类回扩充的非常非常臃肿! 

你这个是滥用了面向对象的继承机制了.而且你也不能为了让派生类添加更多的功能,而要求更改基类.

#7


我是来请高手来解决问题来的!
而并非让高手告诉我回去看书去把!

  硬是把new带出来!对与这个我可new也可以不new!
这和我的问题有任何关系么?
牛头不对马嘴!




class X{
public:
  virtual void Action()=0;
};

class A :public X{
  public:
    virtual void Action(){...};
    vector <_A>  V_A;
  public:
    vector <_A>&  getData(){...return this->V_A;}
};

class B :public X{
public:
  virtual void Action(){...};
  vector <_B>  V_B;
public:
   vector <_B>&  getData(){...return this->V_B;}
}; 
想获得派生类的 数据但又不想使用向下转换
想获为派生类增加方法
又想使用基类的指针获取新增加的方法!但由不愿意使得基类由于
不断重载函数而显得臃肿!

#8


建议楼主看下装饰模式~~~

#9



因为哪个书我看过了

#10


 
 硬是把new带出来!对与这个我可new也可以不new!
这和我的问题有任何关系么?
牛头不对马嘴! 



哈哈,楼主,你还不服气!你看书不精,指教你还不满意吗?
你把用栈的对象的地址付给基类,这是错误的,这不是面像对象设计,面向对象设计
强调多态,动态的,也就是执行期间,所以必须用new.

#11


那好吧!
我就New吧!
struct _A{...};
struct _B{...};
//===========================

class X{
public:
  virtual void Action()=0;
};

class A :public X{
  public:
    virtual void Action(){...};
    vector <_A>  V_A;
  public:
    vector <_A>&  getData(){...return this->V_A;}
};

class B :public X{
public:
  virtual void Action(){...};
  vector <_B>  V_B;
public:
    vector <_B>&  getData(){...return this->V_B;}
};
//=====================================================

问题是:
   X*  pX=new  A;
//既然要new就new一个吧!但下面的问题依旧!谢谢指点!   
  
..............
..............
  过了一段时间我要获得A实例化对象的数据V_A:
则我必须向下转换!
  A*  pA=dynamic_cast <A*>(pX); 然后pA->....
其实我真的不想向下转换!
 
这样做我得付出这样的代价!
class X{
public:
  virtual void Action()=0;
  virtual vector <_A>&  getData(){...}//添加新的虚函数
};
  //派生类相映的函数前面要加上virtual:
class A :public X{
  public:
    virtual void Action(){...};
    vector <_A>  V_A;
  public:
  virtual vector <_A>&  getData(){...return this->V_A;}
};


同样我要获得B的 getData(){...return this->V_B;}
这样又要在class X{....
  virtual vector <_B>&  getData(){...}//添加新的虚函数
};
等不断的进行重载虚函数!将相映的派生类的函数前加virtual;

假如以后我有要添加派生类!
且又要获得派生类的数据这样将
  不断的进行重载虚函数!将相映的派生类的函数前加virtual

最后基类回扩充的非常非常臃肿
!

有没有什么更好的办法呢? 

#12


只会叫人看书的飘过。

#13


把这个基类改变一下:
class X{
public:
  virtual void Action()=0;
  virtual vector <_A>&  getData(){...}//添加新的虚函数
}; 

改成:
template<class T>
class X{
public:
...
  virtural vector<T>&getData(){...}//基类添加了vitural 这个关键字以后,派生类不用添加
};


#14


下面的vc2003代码测试通过:
#include "stdafx.h"
#include <vector>
#include <iostream>
using namespace std;

struct _A{};
struct _B{};
//===========================
template<typename T>
class X{
public:
virtual void Action()=0;
virtual vector <T>&  getData() = 0;
};

class A :public X<_A>{
public:
virtual void Action(){};
vector <_A>  V_A;
public:
vector <_A>&  getData(){return V_A;}
};

class B :public X<_B>{
public:
virtual void Action(){};
vector <_B>  V_B;
public:
vector <_B>&  getData(){return V_B;}
}; 
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}


#15


楼上的高!
但我也有了一个初步的想法!
希望大家实现

   声明返回类型是函数指针的函数

#16


LZ用的是类的继承特性,但是如果滥用继承的话,可是就出现了LZ这样的程序了。。。
无穷无尽。。。。

昨天看了一下“设计模式”中行为模式的前两个。。template模式与strategy模式。。。

这两个模式的区别也就是在使用方面是类的继承与组合的区别。。。。
template使用类的继承。。。而strategy使用组合模式。。。。

我认为strategy模式可以解决LZ的问题。。

#17


看一下这个网页:
http://www.cnblogs.com/chengy024/archive/2008/04/28/1175033.html

最下面有两个链接,,LZ可以下载下来看一下,,肯定会有收获。。。^_^

#1


问题是:
  X*  pX;   
  A    a;...
  pX=&a; 
..............
..............
  过了一段时间我要获得a的数据:
则我必须向下转换!
  A*  pA=dynamic_cast <A*>(pX);
其实我真的不想向下转换!
  ================你没用new对象,你好意思只是把栈对象的地址付给pX

#2


类是用来描述一类事物的抽象。

而你的做法是让这个类中有一个新物种,然后又重新修改该抽象,破坏了抽象描述的定义。

当你需要新的行为的时候,你应该考虑新的行为的抽象与原有行为抽象的联系。

比如你可以为后来新的行为定义某种接口
例如:

原有抽象:
class 动物
{
public:
   virtual  void 叫()=0;
}

class 猫:public 动物
{
virtual  void 叫();
}

新事物:

class 机器猫:public 猫,机器
{
....
}

定义新行为抽象

class 机器
{
virtual void 充电();
}

这样比较好的意义和使用方式来构件新类别。

建议有空看看 ,*的设计模式。

#3


你获得a的数据,干嘛非得跟X扯上关系呢?你直接用A new一个对象不就行了

#4


UP

#5


看看常用的设计模式,应该有符合你要求的

#6


引用楼主的话:
假如以后我有要添加派生类! 
且又要获得派生类的数据这样将 
  不断的进行重载虚函数!将相映的派生类的函数前加virtual 

最后基类回扩充的非常非常臃肿! 

你这个是滥用了面向对象的继承机制了.而且你也不能为了让派生类添加更多的功能,而要求更改基类.

#7


我是来请高手来解决问题来的!
而并非让高手告诉我回去看书去把!

  硬是把new带出来!对与这个我可new也可以不new!
这和我的问题有任何关系么?
牛头不对马嘴!




class X{
public:
  virtual void Action()=0;
};

class A :public X{
  public:
    virtual void Action(){...};
    vector <_A>  V_A;
  public:
    vector <_A>&  getData(){...return this->V_A;}
};

class B :public X{
public:
  virtual void Action(){...};
  vector <_B>  V_B;
public:
   vector <_B>&  getData(){...return this->V_B;}
}; 
想获得派生类的 数据但又不想使用向下转换
想获为派生类增加方法
又想使用基类的指针获取新增加的方法!但由不愿意使得基类由于
不断重载函数而显得臃肿!

#8


建议楼主看下装饰模式~~~

#9



因为哪个书我看过了

#10


 
 硬是把new带出来!对与这个我可new也可以不new!
这和我的问题有任何关系么?
牛头不对马嘴! 



哈哈,楼主,你还不服气!你看书不精,指教你还不满意吗?
你把用栈的对象的地址付给基类,这是错误的,这不是面像对象设计,面向对象设计
强调多态,动态的,也就是执行期间,所以必须用new.

#11


那好吧!
我就New吧!
struct _A{...};
struct _B{...};
//===========================

class X{
public:
  virtual void Action()=0;
};

class A :public X{
  public:
    virtual void Action(){...};
    vector <_A>  V_A;
  public:
    vector <_A>&  getData(){...return this->V_A;}
};

class B :public X{
public:
  virtual void Action(){...};
  vector <_B>  V_B;
public:
    vector <_B>&  getData(){...return this->V_B;}
};
//=====================================================

问题是:
   X*  pX=new  A;
//既然要new就new一个吧!但下面的问题依旧!谢谢指点!   
  
..............
..............
  过了一段时间我要获得A实例化对象的数据V_A:
则我必须向下转换!
  A*  pA=dynamic_cast <A*>(pX); 然后pA->....
其实我真的不想向下转换!
 
这样做我得付出这样的代价!
class X{
public:
  virtual void Action()=0;
  virtual vector <_A>&  getData(){...}//添加新的虚函数
};
  //派生类相映的函数前面要加上virtual:
class A :public X{
  public:
    virtual void Action(){...};
    vector <_A>  V_A;
  public:
  virtual vector <_A>&  getData(){...return this->V_A;}
};


同样我要获得B的 getData(){...return this->V_B;}
这样又要在class X{....
  virtual vector <_B>&  getData(){...}//添加新的虚函数
};
等不断的进行重载虚函数!将相映的派生类的函数前加virtual;

假如以后我有要添加派生类!
且又要获得派生类的数据这样将
  不断的进行重载虚函数!将相映的派生类的函数前加virtual

最后基类回扩充的非常非常臃肿
!

有没有什么更好的办法呢? 

#12


只会叫人看书的飘过。

#13


把这个基类改变一下:
class X{
public:
  virtual void Action()=0;
  virtual vector <_A>&  getData(){...}//添加新的虚函数
}; 

改成:
template<class T>
class X{
public:
...
  virtural vector<T>&getData(){...}//基类添加了vitural 这个关键字以后,派生类不用添加
};


#14


下面的vc2003代码测试通过:
#include "stdafx.h"
#include <vector>
#include <iostream>
using namespace std;

struct _A{};
struct _B{};
//===========================
template<typename T>
class X{
public:
virtual void Action()=0;
virtual vector <T>&  getData() = 0;
};

class A :public X<_A>{
public:
virtual void Action(){};
vector <_A>  V_A;
public:
vector <_A>&  getData(){return V_A;}
};

class B :public X<_B>{
public:
virtual void Action(){};
vector <_B>  V_B;
public:
vector <_B>&  getData(){return V_B;}
}; 
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}


#15


楼上的高!
但我也有了一个初步的想法!
希望大家实现

   声明返回类型是函数指针的函数

#16


LZ用的是类的继承特性,但是如果滥用继承的话,可是就出现了LZ这样的程序了。。。
无穷无尽。。。。

昨天看了一下“设计模式”中行为模式的前两个。。template模式与strategy模式。。。

这两个模式的区别也就是在使用方面是类的继承与组合的区别。。。。
template使用类的继承。。。而strategy使用组合模式。。。。

我认为strategy模式可以解决LZ的问题。。

#17


看一下这个网页:
http://www.cnblogs.com/chengy024/archive/2008/04/28/1175033.html

最下面有两个链接,,LZ可以下载下来看一下,,肯定会有收获。。。^_^