returning structs across classes

This topic is 2626 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I am trying to pass a few variables from one class to another using structs as opposed to arrays as suggested.

When I attempt to create the function in my cpp file it tells me that a ; is required?

My header file has a struct with the function prototype

class test{public:typedef struct NormalArray{	float normX;	float normY;	float normZ;}SAMPLE_STRUCT;	//function prototype	SAMPLE_STRUCT GetNormal();private:};

I am then trying to use this in my cpp file. The cpp file can find the fields and items associated with the struct and seems to be OK except it wont compile.
#include "test.h"	SAMPLE_STRUCT GetNormal()	{ //need ; here?				SAMPLE_STRUCT sample_struct;		sample_struct.normX = 5;		sample_struct.normY = 12;		sample_struct.normZ = 20;		std::cout<<"sample struct is "<<sample_struct.normX<<std::endl;		return sample_struct;	}

I am just trying to use a really simple example just to put the values in print the mout then return the struct. I want to them print this out again to ensure that the values are passed correctly etc.

Do I need to pass by reference using pointers? Am I missing something obvious?

Many thanks

Share on other sites
Identifiers that live inside the test class need to be prefixed with test:: when used outside of the class.

Share on other sites
SAMPLE_STRUCT test::GetNormal(){   // etc}

When you define the body of a class member outside of the class, you need to prefix the method name with the class name and the :: operator.

Share on other sites
There may be more going on here than this, but in your .cpp file, both SAMPLE_STRUCT and GetNormal() need to be qualified, i.e.:
test::SAMPLE_STRUCT test::GetNormal()
Also, there shouldn't be any need to use the 'typedef struct' idiom here.

Share on other sites
You need to let the compiler know where GetNormal comes from. Imaging you have several different classes, all with a member method called GetNormal. Which one are you referring to? Same for SAMPLE_STRUCT when you use it outside "test". So change your cpp to
	test::SAMPLE_STRUCT test::GetNormal()	{ //need ; here?				SAMPLE_STRUCT sample_struct;		sample_struct.normX = 5;		sample_struct.normY = 12;		sample_struct.normZ = 20;		std::cout<<"sample struct is "<<sample_struct.normX<<std::endl;		return sample_struct;	}

Adding "test::" lets the compiler know where the method or type comes from, so to speak.

Share on other sites
A Normal is a well defined type on its own. I would argue you should make it a top level type:
struct Normal{   float x;   float y;   floay z;};

Note that "typedef struct { ... } whatever" idiom is unnecessary in C++. Also avoid using redundant prefixes on member names. A good type name, like "Normal" above, makes it clear.

Compare:
Normal normal;// Needless prefixesfoo(normal.normX, normal.normY, normal.normZ); // bit wordy// No prefixesfoo(normal.x, normal.y, normal.z); // nice!

Share on other sites
I have renamed the struct and have took out the typeDef

I have know tried to use the accessors as you suggested
Test::NormalArray Test::GetNormal() //I get an error telling that function cannot be redeclared outside of the class? { }

If I do Test::NormalArray:: it finds my X,Y,Z values but I cant get it to allow me to do the actual function?

Share on other sites
Post the actual code and the actual error messages please.

Share on other sites
#pragma once#include <windows.h>		// Header File For Windows#include <gl\gl.h>			// Header File For The OpenGL32 Library#include <gl\glu.h>			// Header File For The GLu32 Library#include "console.h"class test{public:struct NormalArray{	float x;	float y;	float z;};	//function prototype	static NormalArray GetNormal();private:};

cpp file
#include "test.h"Enviroment::NormalArray Enviroment::GetNormal() 	{		NormalArray test;		test = 5;		sample_struct.normY = 12;		sample_struct.normZ = 20;		std::cout<<"sample struct is "<<sample_struct.normX<<std::endl;		return sample_struct;	}

I get the error
140 IntelliSense: member function "Enviroment::GetNormal" may not be redeclared outside its class c:\users\phil\desktop\game draft 3\win32opengl2template\enviroment.cpp 132 38 win32template

I now get errors to do with accessing test but I am assuming thats because of the other error.

Just read my error message it may still be linking to my other stuff I'll start again and see what happens

Share on other sites
Why are you using Environment:: when your class is named test?

Share on other sites
Sorry my stupidiyt I have several things open looking at code from one to the other its a whole mess.

I have started agian from scratch with everything closed except for this :)

I have a console,mainopenGL, and my test.

my test.h is
#pragma once#include <windows.h>		// Header File For Windows#include <gl\gl.h>			// Header File For The OpenGL32 Library#include <gl\glu.h>			// Header File For The GLu32 Library#include "console.h"static class test{public:struct NormalArray{	float x;	float y;	float z;};	//function prototype	static NormalArray GetNormal();private:};

my cpp is just
#include "test.h"test::NormalArray test::GetNormal(){	NormalArray test;	test.x = 5;	test.y = 12;	test.z = 20;	std::cout<<"sample struct is "<<test.x<<std::endl;	return test;}

my main is
#include <windows.h>		// Header File For Windows#include <gl\gl.h>			// Header File For The OpenGL32 Library#include <gl\glu.h>			// Header File For The GLu32 Library#include "console.h"#include "test.h"ConsoleWindow console;#include <iostream>using namespace std;int screenWidth=640, screenHeight=480;bool keys[256];double spin=0;double mouse_x, mouse_y;bool LeftPressed = false;//OPENGL FUNCTION PROTOTYPESvoid display();				//called in winmain to draw everything to the screenvoid reshape();				//called when the window is resizedvoid init();				//called in winmain when the program starts.void processKeys();         //called in winmain to process keyboard inputvoid update();				//called in winmain to update variablesvoid drawCube();			//draws a cube of unit size to the screen, with centre at the origin./*************    START OF OPENGL FUNCTIONS   ****************/void display()									{	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			glMatrixMode(GL_PROJECTION);    glLoadIdentity();    gluPerspective(45.0f,(GLfloat)screenWidth/(GLfloat)screenHeight,0.1f,1000.0f);    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();	glTranslatef(0,0,-10);	glPushMatrix();	glRotated(spin,0,1,0);	glColor3f(0,0,1);	drawCube();	glPopMatrix();		test::NormalArray test::GetNormal(){	NormalArray test;	test.x = 5;	test.y = 12;	test.z = 20;	std::cout<<"test struct is "<<test.x<<std::endl;	return test;}    glFlush();	}

There is more mian but its just the windows code stuff. This works fine as it does draw a blue cube as it should just to make sure it works.

My test.h and test.cpp seem fine

When I try to load it in the main though I get the error test::GetNormal() Local function definitions are illegal?

It is static so I shouldn't need any objects do I need to do something to allow my main draw function to access it?

Sorry about before decided to start fresh

Share on other sites
When calling a function you don't put the entire function body with the function call.

Share on other sites
It looks like you pasted your GetNormal() function into the body of your display() function. Is that what you meant to do?

Share on other sites
I could cry with my idiocy. I got rid of everything except the test::GetNormal();
and it works.

That makes complete sense and is fine.

Thanks a lot for all your help

Just a few last questions with regards to structs.
I understand they pass by value? so is it possible to have something like struct student. student.grade = a;

for(int i = 0; i<30 i++)
{
student. student.grade = a;

a = 70;
}

Would this generate 30 different structs all with the same name/attributes? Or would you have to name them all seperatly? If you wanted to change a variable in one of the structs would you have to pass by memory?

Many thanks

Share on other sites
Quote:
 Just a few last questions with regards to structs.I understand they pass by value?
Both structs and classes are passed by value unless you specify otherwise.
Quote:
 so is it possible to have something like struct student. student.grade = a;for(int i = 0; i<30 i++){student. student.grade = a;a = 70;}Would this generate 30 different structs all with the same name/attributes? Or would you have to name them all seperatly?
Your example isn't very clear (IMO, when posting examples such as this, it's generally best to post actual compilable code). But, assuming the intent is to create a local instance of the 'student' struct type, then yes, 30 instances will be created, but each will be temporary and will only exist for that iteration of the loop.
Quote:
 If you wanted to change a variable in one of the structs would you have to pass by memory?
If by 'pass by memory' you mean pass by (conceptual) reference (reference or pointer in C++), then yes, that would be one way to do it. (The question lacks context though, so it's hard to provide a more specific answer than that.)

Share on other sites
If you want to create 30 students, use an array. If you want to handle an arbitrary amount of students, use a collection like std::vector<Student>.