简体   繁体   中英

Cast to base class from base pointer from different base class (preferably without dynamic_cast)

class Model {};

class AbstractModel {};
class TableModel : public AbstractModel {};

class CustomerModel : public TableModel, public Model {};
class ItemModel : public TableModel, public Model {};
...

The requirement is that each TableModel subclass has to provide a set of features shared among all subclasses (CustomerModel, ItemModel, ...). As TableModel and AbstractModel is immutable, the set of features is defined in the Model class and implemented in each subclass (CustomerModel, ItemModel, ...).

The problem now is that other parts of the application only have access to an AbstractModel pointer, and in order to access the set of features defined in Model this pointer has to be casted from AbstractModel to Model (we assume that each TableModel subclass also implements Model).

Is there any possibility to do so without using a dynamic_cast? Any recommendations to a different design providing the same functionality?

First of all, this is not possible without dynamic_cast . However your requirement sounds a bit odd to me. "Each TableModel subclass has to provide a set of features" sounds a lot like TableModel should define that set by using pure virtual functions. You say TableModel is immutable, so I guess you get it from some kind of library/framework and are implementing your own set of subclasses and it is your set of requirements we are talking about. In that case I would suggest you derive one abstract class of TableModel, defining your requirements as pure virtual functions and derive the actual implementations from that abstract class:

//immutable/library
class AbstractModel {};
class TableModel : public AbstractModel {};

//your code:
class MyOwnTableModel : public TableModel
{
public: 
  void implementThisRequrement() = 0;
};

class CustomerModel : public MyOwnTableModel { /*...*/ };
class ItemModel : public MyOwnTableModel { /*...*/ };

After that, all you need to do is a simple downcast ( dynamic_cast ) from AbstractModel to MyOwnTableModel, no need to cross-cast. However, if you could tell us more about the design you have there, maybe there is an even simpler and better solution - dynamic_cast almost ever is evidence for some design flaws.

First, why not use dynamic_cast?

Second, why not make TableModel inherit from Model? (After all, a "table model" sounds like a specialized version of a "model")

By "immutable", do you mean in the Java/.NET sense where an object can't change its state once it's created? Or do you mean you can't change the classes because they're part of some library? My first guess was the first.

If you don't want to use dynamic_cast (which is part of C++'s RTTI functionality), you'll have to implement your own form of RTTI. For example, Microsoft's MFC does this by deriving all classes from a CObject superclass that contains runtime type information. Microsoft COM also does this by requiring all interfaces to derive from the IUnknown interface, which contains a QueryInterface method that is basically equivalent to dynamic_cast.

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.

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