Consider the following example
class GameObject {
vec3 position;
SphereCollider collider;
// ...
};
SphereCollider* GameObject::getCollider(){
return &collider;
}
class SphereCollider {
vec3 position;
float radius;
};
You can notice that in this design there is a duplicity of a member variable position
shared among more classes. The radius
is there to show there can be other data members.
The SphereCollider is later used for collision detection and I have more classes of GameObject (with no common ancestor) which compose the SphereCollider.
What is the cleanest way to handle this situation design and performance wise? Is there a convention in this?
There are few solutions in my mind, but none of them is perfect. Can you think of a better solution?
1) Persistent data member access via getter/setter
Cons: No direct access to the data member inside the class. Is there a convention to tell this truth to the programmer who will further work on this class?
void GameObject::setPosition(vec3& pos){
position = pos;
colliser->setPosition(pos);
}
vec3 GameObject::getPosition(){
return position;
}
2) Remove redundancy and use getter/setter access to the SphereCollider
Cons: similar to 1)
class GameObject {
SphereCollider collider;
};
void GameObject::setPosition(vec3& pos){
colliser->setPosition(pos);
}
3) Reference/pointer from SphereCollider to GameObject data members
Cons: Reallocating (e.g. std::vector) the GameObject may cause troubles. Is there a way of telling the user of this class?
class GameObject {
vec3 position;
SphereCollider collider;
public:
GameObject(){
collider = SphereCollider(position);
}
};
class SphereCollider {
const vec3& position;
float radius;
public:
Collider(vec3& pos)
: position(pos)
{
}
};
4) Propagate data to the SphereCollider on demand
Cons: User can store the reference to the collider an skip using getCollider();
SphereCollider* GameObject::getCollider(){
collider->setPosition(position);
return &collider;
}