type casting of a ptr to a c struct

  • Thread starter Chandra Shekhar Kumar
  • Start date
C

Cgacc20

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.

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();
};


Would this be valid, or terrible ideas so far and something else is likely
better?
 
R

Rob Williscroft

Cgacc20 wrote in
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.x
<< ","
<< xyz.y
<< ","
<< xyz.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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top