Sign in to follow this  
Raeldor

C++/CLI Forward Class Declaration Confusion

Recommended Posts

Raeldor    254
Hi All, My Vector3 class uses my Matrix class and vice versa, but a forward declaration of the Vector3 class doesn't seem to satisfy the compiler. I still get an 'undefined type' error. My code looks like...
	value class Vector3;

	public ref class MNWMatrix
	{
	private:
		NW::NWMatrix* m_matrix;
		bool m_owned;
	public:
		MNWMatrix() {m_matrix=new NW::NWMatrix(); m_owned=true;}
		MNWMatrix(IntPtr in_unmanagedPtr) {m_matrix=(NW::NWMatrix*)in_unmanagedPtr.ToPointer();}
		~MNWMatrix() {if (m_owned) delete m_matrix;}
		!MNWMatrix() {if (m_owned) delete m_matrix;}
		IntPtr GetUnmanagedPtr() {return IntPtr(m_matrix);}

		void MakeIdentity() {m_matrix->MakeIdentity();}
		void MakeScale(float in_scaleX, float in_scaleY, float in_scaleZ)
		{*(NW::NWMatrix*)m_matrix=NW::NWMatrixScale(in_scaleX, in_scaleY, in_scaleZ);}
		void MakeTranslation(float in_x, float in_y, float in_z)
		{*(NW::NWMatrix*)m_matrix=NW::NWMatrixTranslation(in_x, in_y, in_z);}
		void MakeRotate(float in_x, float in_y, float in_z)
		{*(NW::NWMatrix*)m_matrix=NW::NWMatrixRotate(NW::Vector3(in_x, in_y, in_z));}

		Vector3^ GetPosition()
		{
			NW::Vector3 pos=m_matrix->GetPosition();
			return gcnew Vector3(pos.x, pos.y, pos.z);
		}

		static inline MNWMatrix^ operator* (MNWMatrix^ in_matrix, MNWMatrix^ in_matrix2)
		{
			NW::NWMatrix* result=new NW::NWMatrix();
			*result=(*(NW::NWMatrix*)in_matrix->GetUnmanagedPtr().ToPointer())*(*(NW::NWMatrix*)in_matrix2->GetUnmanagedPtr().ToPointer());
			return gcnew MNWMatrix(IntPtr(result));
		}
	};

	public value class Vector3
	{
	public:
		Vector3(float in_x, float in_y, float in_z) {x=in_x; y=in_y; z=in_z;}

		float x, y, z;

		inline float Length() {return sqrt(x*x+y*y+z*z);}
		inline void Normalize() {float l=Length(); x/=l; y/=l; z/=l;}

		void Transform(MNWMatrix^ in_matrix)
		{
			NW::Vector3 vector=NWVectorTransform(*(NW::NWMatrix*)in_matrix->GetUnmanagedPtr().ToPointer(), NW::Vector3(x, y, z));
			x=vector.x;
			y=vector.y;
			z=vector.z;
		}

		static Vector3 operator- (Vector3 in_left, Vector3 in_right) {return Vector3(in_left.x-in_right.x, in_left.y-in_right.y, in_left.z-in_right.z);}
		static Vector3 operator+ (Vector3 in_left, Vector3 in_right) {return Vector3(in_left.x+in_right.x, in_left.y+in_right.y, in_left.z+in_right.z);}
		static void operator+= (Vector3 in_left, Vector3 in_right) {in_left.x+=in_right.x; in_left.y+=in_right.y; in_left.z+=in_right.z;}
		static Vector3 operator*= (Vector3 in_left, float in_mult) {return Vector3(in_left.x*=in_mult, in_left.y*=in_mult, in_left.z*=in_mult);}
		static Vector3 operator* (Vector3 in_left, float in_mult) {return Vector3(in_left.x*in_mult, in_left.y*in_mult, in_left.z*in_mult);}
		static Vector3 operator/ (Vector3 in_left, float in_mult) {return Vector3(in_left.x/in_mult, in_left.y/in_mult, in_left.z/in_mult);}
	};

To be honest, with this being a managed language I wasn't expecting to have to forward declare my classes at all... I don't have to in C#, so why do I have to in C++/CLI? Are there some subtleties of the forward declarations for C++/CLI I am unaware of? Thanks! Rael

Share this post


Link to post
Share on other sites
Raeldor    254
Ack, nope... still having problems. When I try and do this by forward declaring the matrix class instead, I get a 'use of undefined type MNWMatrix'. Do I still need to declare all my function headers in a header file and ship my code into a seperate file like in C++? I thought managed was supposed to be smarter than this?

ref class MNWMatrix;

public value class Vector3
{
public:
Vector3(float in_x, float in_y, float in_z) {x=in_x; y=in_y; z=in_z;}

float x, y, z;

inline float Length() {return sqrt(x*x+y*y+z*z);}
inline void Normalize() {float l=Length(); x/=l; y/=l; z/=l;}

void Transform(MNWMatrix^ in_matrix)
{
NW::Vector3 vector=NWVectorTransform(*(NW::NWMatrix*)in_matrix->GetUnmanagedPtr().ToPointer(), NW::Vector3(x, y, z));
x=vector.x;
y=vector.y;
z=vector.z;
}

static Vector3 operator- (Vector3 in_left, Vector3 in_right) {return Vector3(in_left.x-in_right.x, in_left.y-in_right.y, in_left.z-in_right.z);}
static Vector3 operator+ (Vector3 in_left, Vector3 in_right) {return Vector3(in_left.x+in_right.x, in_left.y+in_right.y, in_left.z+in_right.z);}
static void operator+= (Vector3 in_left, Vector3 in_right) {in_left.x+=in_right.x; in_left.y+=in_right.y; in_left.z+=in_right.z;}
static Vector3 operator*= (Vector3 in_left, float in_mult) {return Vector3(in_left.x*=in_mult, in_left.y*=in_mult, in_left.z*=in_mult);}
static Vector3 operator* (Vector3 in_left, float in_mult) {return Vector3(in_left.x*in_mult, in_left.y*in_mult, in_left.z*in_mult);}
static Vector3 operator/ (Vector3 in_left, float in_mult) {return Vector3(in_left.x/in_mult, in_left.y/in_mult, in_left.z/in_mult);}
};

public value class Vector2
{
public:
Vector2(float in_x, float in_y) {x=in_x; y=in_y;}

float x, y;

inline float Length() {return sqrt(x*x+y*y);}
inline void Normalize() {float l=Length(); x/=l; y/=l;}
inline float Dot(Vector2 in_right) {return x*in_right.x+y*in_right.y;}
};

public ref class MNWMatrix
{
private:
NW::NWMatrix* m_matrix;
bool m_owned;
public:
MNWMatrix() {m_matrix=new NW::NWMatrix(); m_owned=true;}
MNWMatrix(IntPtr in_unmanagedPtr) {m_matrix=(NW::NWMatrix*)in_unmanagedPtr.ToPointer();}
~MNWMatrix() {if (m_owned) delete m_matrix;}
!MNWMatrix() {if (m_owned) delete m_matrix;}
IntPtr GetUnmanagedPtr() {return IntPtr(m_matrix);}

void MakeIdentity() {m_matrix->MakeIdentity();}
void MakeScale(float in_scaleX, float in_scaleY, float in_scaleZ)
{*(NW::NWMatrix*)m_matrix=NW::NWMatrixScale(in_scaleX, in_scaleY, in_scaleZ);}
void MakeTranslation(float in_x, float in_y, float in_z)
{*(NW::NWMatrix*)m_matrix=NW::NWMatrixTranslation(in_x, in_y, in_z);}
void MakeRotate(float in_x, float in_y, float in_z)
{*(NW::NWMatrix*)m_matrix=NW::NWMatrixRotate(NW::Vector3(in_x, in_y, in_z));}

Vector3 GetPosition()
{
NW::Vector3 pos=m_matrix->GetPosition();
return MNW::Vector3(pos.x, pos.y, pos.z);
}

static inline MNWMatrix^ operator* (MNWMatrix^ in_matrix, MNWMatrix^ in_matrix2)
{
NW::NWMatrix* result=new NW::NWMatrix();
*result=(*(NW::NWMatrix*)in_matrix->GetUnmanagedPtr().ToPointer())*(*(NW::NWMatrix*)in_matrix2->GetUnmanagedPtr().ToPointer());
return gcnew MNWMatrix(IntPtr(result));
}
};

Share this post


Link to post
Share on other sites
Twinsen2    110
I seems as thou forward decs are good only if u are declaring funcs in a header but dont need thier functionality.
ie, you need that type but the type isnt going to get used yet.
Because you are using a vector type in the header file, eg.
v1.x ect you need access to more information.

Try only defing functions in ur header file

Then, when you do need the vector3's methods, include the header file into your cpp file.

Why not just include vector3 in the header? you ask? It creates longer build times, putting it in the cpp will reduce them imensly.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this