Reputation: 4501
okay - maybe this is a silly question and cast operators do this already inherently..
What I have:
some external class definition of a 4x4 Matrix
some own 4x4 Matrix class
both classes interally simply store a float[16];
i'd like to define in my Matrix class a cast operator so that I can do things like:
MyMatrix4x4 m;
OtherMatrix4x4(m).someFunctionDefinedInOtherMatrix4x4();
SomeFunctionThatTakesOtherMatrix4x4(OtherMatrix4x4(m));
And I don't want this operator to copy any data - the functions should simply operate on the same float[16] data
How to do that?
Upvotes: 1
Views: 2178
Reputation: 5439
Just to present a different solution presenting inheritance. These would allow the use of code you posted above. However this is not a cast operator.
class MyMatrix4x4 {
public:
float f;
};
class OtherMatrix4x4 : MyMatrix4x4 {
public:
OtherMatrix4x4(MyMatrix4x4 &matrix)
{
f = matrix.f;
}
void someFunctionDefinedInOtherMatrix4x4();
};
Upvotes: 0
Reputation: 473407
And I don't want this operator to copy any data - the functions should simply operate on the same float[16] data
I don't want to create any data on the heap. want this to work with values on the stack - and also for convenciance i'd like to have a cast operator
Well that's not going to happen. C++'s aliasing rules pretty much forbid that.
You can use pointer-casts to do "pretend this is something else", but you can't use object casts to do that. You could cast a pointer to a stack object to a pointer to your type of object:
MyMatrix4x4 m;
OtherMatrix4x4 * o = (OtherMatrix4x4 *) &m;
However, there are two problems. First, o
will last only as long as m
does. It isn't an object; it's a pointer to a different object. Second, doing this is (in general) undefined behavior (in part due to violating aliasing: two unrelated types overlapping). Oh, odds are that it will work. But you're off the map as far as what C++ will guarantee.
This smells of a premature optimization. Do you really think that copying 16 floats is that big of a performance issue? If it is, then why not just use OtherMatrix4x4
in your code instead of MyMatrix4x4
?
Upvotes: 3
Reputation: 258598
OtherMatrix4x4(m)
This isn't a cast operator, it's a conversion constructor.
Suppose the following definition of MyMatrix4x4
:
struct MyMatrix4x4
{
float x[16];
};
The the following should do it:
struct OtherMatrix4x4
{
float* x;
OtherMatrix4x4(MyMatrix4x4& other)
{
x = other.x;
}
void foo()
{
x[0] = 0;
}
};
To test:
MyMatrix4x4 a = {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}};
OtherMatrix4x4(a).foo();
cout << b.x[0]; //will output 0, not 1
EDIT Here's the version where you cant edit the other matrix:
struct OtherMatrix4x4
{
float x[16];
void foo()
{
x[0] = 0;
}
};
struct MyMatrix4x4
{
float* x;
operator OtherMatrix4x4()
{
OtherMatrix4x4 other;
x = other.x;
return other;
}
};
MyMatrix4x4 m;
OtherMatrix4x4(m).foo();
Upvotes: 1