# Problem when wrapping libraries

This topic is 3439 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

For this example, I will use the library Cal3d, but it would be the same for pretty much any other library. We have 2 classes, CalCoreModel and CalModel. These are used like: CalCoreModel coreModel("core"); CalModel model(&coreModel); Now, in my engine I want to "wrap" these classes, so I can add some "smart" functionality I want,and maybe make my code API-indepedent(so I could substitute Cal3D when another lib in the future). So it becomes:
class MyCoreModel
{
private:
CalCoreModel calCoreModel;
public:
MyCoreModel(std::string name):calCoreModel(name){}
{
}
};

class MyModel
{
private:
CalModel calModel;
public:
MyModel(MyCoreModel& core):calModel(???){}//PROBLEM
};


As you can see, in order to create the CalModel, I need to take a look at the "guts" of MyCoreModel and get the CalCoreModel private member. How do I do this? If I add a GetCalCoreModel() member function in MyCoreModel, then I have exposed some of the implementation details into the public interface. The "friend" approach is usually a codesmell. Is there any other way this can be succeded sanely?

##### Share on other sites
One approach, if you have to use the constructor to construct a CalModel object (there should be some other Load function though)
class MyCoreModel{private:  CalCoreModel calCoreModel;public:  // In the header file, you can forward declare class CalModel;  // You will include the header file that declares CalModel in the .cpp  // to reduce header dependencies.  void ConstructModel(CalModel * model)  {     model = new CalModel(&calCoreModel);  }};class MyModel{private:  CalModel * calModel;public:  MyModel(MyCoreModel& core) : calModel(0)  {     core.ConstructModel(calModel); // if new throws, calModel should still be 0  }  ~MyModel  {     delete calModel;  }};

That would be one clean way to go about it. Another way is similar to that, but rather than use the constructor of CalModel, you would find some other function that accomplishes the same thing. That way, you don't have to use pointers and memory allocations/cleanup.

##### Share on other sites
One option is to move to abstract base classes for your personal interfaces and have implementations perform checked_casts where necessary.
// interface:struct ICoreModel {  virtual void LoadCoreAnim(std::string name) = 0;  virtual ~ICoreModel() = 0;};struct IModel {  virtual ~IModel() = 0;};std::auto_ptr<ICoreModel> create_cal3d_core_model(std::string name);std::auto_ptr<IModel> create_cal3d_model(ICoreModel & core);// implementation:struct Cal3DCoreModel : ICoreModel {  CalCoreModel calCoreModel;  Cal3DCoreModel(std::string name) : calCoreModel(name) {}  virtual void LoadCoreAnim(std::string name) { calCoreModel.loadCoreAnimation(name); }  virtual Cal3DCoreModel() {}};struct Cal3DModel : IModel {  CalModel calModel;  Cal3DModel(ICoreModel & core) : calModel(checked_cast<Cal3DCoreModel &>(core).calCoreModel) {}};std::auto_ptr<ICoreModel> create_cal3d_core_model(std::string name) {  std::auto_ptr<ICoreModel> temp(new Cal3DCoreModel(name));  return temp;}std::auto_ptr<IModel> create_cal3d_model(ICoreModel & core) {  std::auto_ptr< IModel > temp(core);  return temp;}

• 18
• 11
• 17
• 9
• 51
• ### Forum Statistics

• Total Topics
631397
• Total Posts
2999793
×