Cgacc20 wrote in news:20***************************@mb-m26.aol.com:
I have a c struct from old code that cannot be modified and I am
trying to write a wrapper C++ class around it.
This class is often passed as a pointer to some c functions of a
library and I wanted to keep my new class transparent and compatible
with those functions. That is, when using the code, I should be able
to do either:
oldVector xyz;
function( &xyz );
myVector xyz;
function( &xyz );
My original implementation solved the issue using inheritance. That
is, in pseudo code:
// old code
typedef struct {float x, y, z;} oldVector;
/// my class
class myVector : public oldVector
{
/// new methods here
};
This worked fine for my needs, but I wanted to change myVector class
to be a template which would likely prevent the inheritance.
I know the alignment in the compilers I will be should result in an
identical memory layout.
I was wondering if it was possible to use type casting to work around
it.
This is possible, but lets try somthing different first.
Basically, I was thinking something along the lines of:
template <class T> class Vec3
{
public:
T x, y, z;
// other methods....
};
class myVector : public Vec3< float >
{
operator oldVector();
// but for a pointer.... would this be valid????
operator *oldVector();
};
I'm guessing from what you say that you want to eventually make
myVector a class template as well, If so it would be usefull to
know what you intend to paramitise it on? I've guessed Flaot
bellow.
Anyway:
#include <iostream>
#include <ostream>
#include <vector>
#include <cstddef> /* for std::size_t */
/* Your old code:
*/
struct oldVector { float x, y, z; };
/* new template:
*/
template <typename Float>
class vec3
{
public:
// new stuff here
public: // private: /* maybe? */
Float x, y, z;
};
/* specialization for backward compatibility:
*/
template <>
class vec3< float >: public oldVector
{
public:
// all your new stuff again
/* uncomment _make_too_big_ to see check the compile time assert works:
*/
//char _make_too_big_;
};
template <std::size_t szA, std::size_t szB>
struct ASSERT_EQUAL_SIZE_helper;
template <std::size_t szT>
struct ASSERT_EQUAL_SIZE_helper< szT, szT>
{
static void is_equal_size() {}
};
template <typename A, typename B>
struct ASSERT_EQUAL_SIZE:
ASSERT_EQUAL_SIZE_helper< sizeof(A), sizeof(B) >
{
};
template <typename Float>
class myVector : public vec3< Float >
{
public:
myVector(Float xx, Float yy, Float zz)
{
x = xx;
y = yy;
z = zz;
}
~myVector(); // for assert
};
template <typename Float>
inline myVector< Float >::~myVector()
{
/* do nothing dtor (no assert needed) */
}
template <>
myVector< float >::~myVector()
{
/* check the size of *this is the same as oldVector
*/
ASSERT_EQUAL_SIZE< myVector< float >, oldVector >
::
is_equal_size()
;
}
void test(oldVector *xyz, std::size_t n)
{
for (std::size_t i = 0; i < n; ++i)
{
std::cout
<< xyz[i].x
<< ","
<< xyz[i].y
<< ","
<< xyz[i].z
<< std::endl
;
}
}
int main()
{
typedef float float_t;
std::vector< myVector< float_t > > a;
myVector< float_t> v(1, 2, 3);
a.push_back(v);
a.push_back(v);
a.push_back(v);
test(&a[0], a.size());
}
The obove compiled on g++ (gcc 3.2) and MSVC 7.1.
HTH
Rob.
--
http://www.victim-prime.dsl.pipex.com/