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':
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:
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:
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:
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. So you do not need to know that objA was an objB.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.