简体   繁体   English

如何动态创建相关类型?

[英]How can I create related types dynamically?

How do I determine the type of a class that is related to another class dynamically? 如何动态确定与另一个类相关的类的类型?

I have figured out a solution, the only problem is that I ended up having to use a define that has to be used in all of the derived classes. 我已经找到了解决方案,唯一的问题是我最终不得不使用必须在所有派生类中使用的定义。

Is there a simpler way to do this that doesn't need upkeep for ever class that is added? 有没有更简单的方法可以做到这一点,而无需为所添加的类进行任何维护?

Things to note: both the class and the related class will always have their respective base class, the different classes can share a related class, and as in the example I would like the control class to own the view. 注意事项:该类和相关类都将始终具有各自的基类,不同的类可以共享一个相关类,并且在示例中,我希望控件类拥有视图。

This is what I have now. 这就是我现在所拥有的。 The only thing I have to upkeep is the switch, but I would like to have it so I only need to add code insted of going back and changing it. 我唯一需要维护的是开关,但是我想拥有它,因此只需要添加回溯和更改它的代码即可。

#include <iostream>
#include <string>

class model 
{
public:
  model( int id ) : id(id) {}

  int id;
};

class view 
{
public:
  view( model *m ) {}

  virtual std::string display() 
  {
     return "view";
  }
};

class otherView : public view 
{
public:
  otherView( model *m ) : view(m) {}

  std::string display() 
  {
     return "otherView";
  }
};


class control 
{
public:
  control( model *m ) : m_(m), v_( createRelated() ) {}

  ~control() 
  { 
     delete v_; 
  }
  std::string display() 
  {
     if ( v_ )
        return v_->display();
     return "No view";
  }

  view *createRelated() 
  {
     switch( m_->id )  
     {
     case 0:
       return new view( m_ );
     case 1:
       return new otherView( m_ );
     default:
       return NULL;
     }
  }

  model *m_;
  view  *v_;
};

int main( void ) {
  model m(0);
  model om(1);
  model nm(2);

  control c1( &m );
  control c2( &om );
  control c3( &nm );

  std::cout << c1.display() << std::endl;
  std::cout << c2.display() << std::endl;
  std::cout << c3.display() << std::endl;
}

A possible solution would be to change model to accept a pointer to a function that creates the related class, instead of passing an 'id': 一个可能的解决方案是更改模型以接受指向创建相关类的函数的指针,而不是传递“ id”:

typedef view* (*make_function)(model*);

class model
{
public:
    model(make_function a_make) : make_(a_make) {}
    view* make() const { return make_(this); }
...
private:
    make_function make_;
};

Each of view classes to provide a static method that creates an instance of itself: 每个view类都提供一个静态方法来创建其自身的实例:

class view
{
public:
    static view* make(model* m) {  return new view(m); }
};

class otherView: public view
{
public:
    static view* make(model* m) {  return new otherView(m); }
};

Then 'createRelated()' would become: 然后,“ createRelated()”将变为:

view* control::createRelated()
{
    return m_->make();
}

Example use: 使用示例:

model m1(&view::make);
model m2(&otherView::make);

Hope that helps. 希望能有所帮助。

您基本上是在寻找一种称为Virtual Constructor的技术。

您是否正在寻找工厂设计模式

You might need some virtual functions. 您可能需要一些虚拟功能。 Even if you pass an object of type B derived from type A: 即使您传递了从A类型派生的B类型对象:

void f(A &objA) {
  objA.f();
}

int main() {
  B objB;
  f(objB);
  return 0;
}

if A::f() is defined to be virtual, then B::f() will be invoked. 如果将A :: f()定义为虚拟的,则将调用B :: f()。 So you do not need to know that objA was an objB. 因此,您无需知道objA是objB。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM