I'm working on a university project, it's subject being the animation of articulated figures. The code is written in C++ and I'm using Qt's UI framework.
The business logic of the application is separated into a wrapper class, let's call this Wrapper. This uses the singleton design pattern, because multiple widgets (windows, tabs etc.) are accessing it and I want to be sure there's only one instance.
Here's the code (simplified) illustrating the class hierarchy of the Wrapper class:
class Wrapper { private: vector<Skeleton> _skeletons; public: static Cor3d& getInstance() { static Cor3d instance; return instance; } // other data members and functions } class Skeleton { private: vector<Joint> _joints; } class Joint { private: DCoordinate3 _rotation_axis; } class DCoordinate3 { private: double _data[3]; } The user should be able to build their figures (add a skeleton, add joints change their coordinates etc.). Let's suppose that the user wants to change the x coordinate of the rotation axes. Here's what I'm currently doing:
double DCoordinate3::x() const { return _data[0]; } double Joint::rotation_axes_x() const { return _rotation_axis.x(); } double Skeleton::joint_rotation_axes:x(unsigned int joint_id) const { return _joints[joint_id].rotation_axes_x(); } double Wrapper::skeleton_joint_rotation_axes_x(unsigned int skeleton_id, unsigned int joint_id) const { return _skeletons[skeleton_id].joint_rotation_axes(joint_id); } can be called like:
double x = Wrapper::getInstance().skeleton_joint_rotation_axes_x(1, 25); The problem with this is that I had to write four get methods to get a single coordinate. The classes contain more data in reality, and writing all the get/set methods will result in bloated, hard to maintain code.
Question: Is there a better way to be able to manipulate the data in this class hierarchy (without violating OOP and encapsulation principles)?
Other solutions I have thought of:
Returning the "mid-level" objects (Skeleton, Joint)
Skeleton Wrapper::get_skeleton(unsigned int skeleton_id) { return _skeletons[skeleton_id]; } // same with Joint and DCoordinate3The problem with this is that the classes might get big and making a copy of them every time might be an issue.
Returning references to objects. The same data is accessed from multiple widgets, this might cause references to objects which no longer exist (See: Scott Meyers, Effective C++ 3rd Edition, 2005, Item 21)
declaring the Wrapper class friend of the others
Question (reformulated): What is the OOP way to elegantly solve this problem (from the ones that I described or something else)? Or what would be an "accepted" solution?