Jump to content
  • Advertisement
Sign in to follow this  
mikeman

Problem when wrapping libraries

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

If you intended to correct an error in the post then please contact us.

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){}
  void LoadCoreAnim(std::string name)
  {
    calCoreModel.loadCoreAnimation(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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!