Reputation: 23
I made a 3d vector class like this
struct Vector3D {
float x;
float y;
float z;
Vector3D() {
x = 0;
y = 0;
z = 0;
}
Vector3D(float x1,float y1,float z1=0) {
x = x1;
y = y1;
z = z1;
}
//member functions for operator overloading, dot product, etc.
};
But now I want to make a child class specific to Euler angles. So far I have
struct Euler3D : Vector3D {
float roll;
float pitch;
float yaw;
};
How do I make the class so that roll pitch and yaw reference the same data as x, y and z? I think it involves union
or something.
I want to be able to achieve something like this:
Euler3D a = {1, 2, 3};
cout << a.x << endl; // prints 1
a.x = 1.5;
cout << a.roll << endl; //prints 1.5
Thank you
Upvotes: 2
Views: 313
Reputation: 51825
How do I make the class so that roll pitch and yaw reference the same data as x, y and z?
The clue is in the word "reference" - you can make the members of the derived class references to the corresponding members in the base.
EDIT: As pointed out in the comments, this will also require the class to have a copy constructor:
struct Euler3D : Vector3D {
float& roll = Vector3D::x; // You don't actually need the "Vector3D::" ...
float& pitch = Vector3D::y; // ... qualifiers here, but using them adds ...
float& yaw = Vector3D::z; // ... clarity for more complex cases.
Euler3D() { } // Should have def. ctor as we define the copy!
Euler3D(const Euler3D& rhs) : Vector3D(rhs) { }
};
Here's a short piece of code to illustrate how this could work:
int main()
{
Euler3D* e3d = new Euler3D;
e3d->roll = 1.1f;
e3d->pitch = 2.2f;
e3d->yaw = 3.3f;
Vector3D* v3d = dynamic_cast<Vector3D*>(e3d);
std::cout << v3d->x << " " << v3d->y << " " << v3d->z << std::endl;
Euler3D e3d2 = *e3d;
std::cout << e3d2.roll << " " << e3d2.pitch << " " << e3d2.yaw << std::endl; // Copied from RHS
e3d2.roll = 4.4f; e3d2.pitch = 5.5f; e3d2.yaw = 6.6f;
std::cout << e3d2.roll << " " << e3d2.pitch << " " << e3d2.yaw << std::endl; // Changed
std::cout << v3d->x << " " << v3d->y << " " << v3d->z << std::endl; // Not changed
return 0;
}
Upvotes: 1
Reputation: 238351
How do I make the class so that roll pitch and yaw reference the same data as x, y and z?
You cannot.
Since you want to refer to an object, you could use reference instead, but that breaks copying - you can fix copy constructor by using user defined one. Furthermore (just like your duplication) this introduces unnecessary memory overhead.
What you can do is write a function that returns reference to the member. like this:
struct Euler3D : Vector3D {
float& roll() { return x; }
But this is not ideal either because you probably need at least a second set of overloads for const, so plenty of boilerplate.
I think it involves union or something.
You can use an union to have aliased members, but then you cannot have the inheritance. This is allowed:
struct Euler3D {
union { float x, roll; };
union { float y, pitch; };
union { float z, yaw; };
};
Which you can use exactly as in your snippet.
Upvotes: 2