• 14
• 12
• 9
• 10
• 13

# [C++] Storing different types of variables for later use

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

## Recommended Posts

Hi all! I'm working on a simple game engine project with the help of tutorials. I'm not new to programming or programming with OpenGL but I'm new to CPP. I need a method to draw variables I calculate before rendering the world polygons as the last thing before I swap the buffers. As for now the polygons get drawn on top of the text and UI items. The things I want to draw range from strings to integers. I need something to store them all in for later use. In example, a text message should be stored along with the coordinates it is going to be displayed at and the size and 3 floats for the color. I think I could make all these variables extern(global?) and just call them later on, but I heard that is bad practice. Can I store all these different variables in a single 2dimensional matrix? How would the function look like?

##### Share on other sites
I think what you want is to create something like a struct?

struct TextMessage{  string message;  int x, y;  float r, g, b;};

Then you can have an array (better yet use a vector) and store a number of these for later use. Unless I interpret your question wrong.

##### Share on other sites
Yes! This is exactly what Im looking for. So far it works from one file. How can I forward declarate said struct so I can store things in it from elsewhere?

UI.cpp
struct uiMsg{	const char * msgText;	int x, y;	float fR, fG, fB;} title, projectname

UI.h
struct uiMsg;

camera.cpp
		title.msgText = "Current Frames Per Second: %d", int(framesPerSecond);		title.x = 15;		title.y = 12;		title.fR = .8;		title.fG = .8;		title.fB = .8;

debug/errlog
Quote:
 1>.\Camera.cpp(61) : error C2065: 'title' : undeclared identifier1>.\Camera.cpp(61) : error C2228: left of '.msgText' must have class/struct/union1> type is ''unknown-type''1>.\Camera.cpp(62) : error C2065: 'title' : undeclared identifier1>.\Camera.cpp(62) : error C2228: left of '.x' must have class/struct/union1> type is ''unknown-type''1>.\Camera.cpp(63) : error C2065: 'title' : undeclared identifier1>.\Camera.cpp(63) : error C2228: left of '.y' must have class/struct/union1> type is ''unknown-type''1>.\Camera.cpp(64) : error C2065: 'title' : undeclared identifier1>.\Camera.cpp(64) : error C2228: left of '.fR' must have class/struct/union1> type is ''unknown-type''1>.\Camera.cpp(65) : error C2065: 'title' : undeclared identifier1>.\Camera.cpp(65) : error C2228: left of '.fG' must have class/struct/union1> type is ''unknown-type''1>.\Camera.cpp(66) : error C2065: 'title' : undeclared identifier1>.\Camera.cpp(66) : error C2228: left of '.fB' must have class/struct/union1> type is ''unknown-type''1>Generating Code...1>Build log was saved at "file://c:\Users\Maarten\Documents\Albedo\Release\BuildLog.htm"1>Albedo - 12 error(s), 3 warning(s)========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I think the header file is wrong. I got the Compiler Error C2011 but the description is rather vague.

##### Share on other sites
Quote:
 Original post by DefeatistI need a method to draw variables I calculate before rendering the world polygons as the last thing before I swap the buffers. As for now the polygons get drawn on top of the text and UI items. The things I want to draw range from strings to integers. I need something to store them all in for later use. In example, a text message should be stored along with the coordinates it is going to be displayed at and the size and 3 floats for the color.

In other words, you want to display text labels?

Quote:
 I think I could make all these variables extern(global?) and just call them later on, but I heard that is bad practice.

I don't see why you'd need to use extern or global variables for this. There are better ways to design something like this. How familiar are you with software design?

Quote:
 Can I store all these different variables in a single 2dimensional matrix? How would the function look like?

As nhatkthanh already showed, a struct or class makes a lot of sense here. You can do the same for other objects, such as sprites or models. It's probably a good idea to build/use a point or vector class for the position, and a color struct for the color, because these things will likely be used in multiple places, so it'll make them easier and more obvious to work with.

##### Share on other sites
To react to your latest post, you've made several mistakes. Here's what to do:
• place the struct definition in the header file, do not create instances of it there (that will cause all files that include that header to get their own 'title' and 'projectname' variables!)
• add inclusion guards to the header (otherwise you'll get double definitions when you include the header into multiple other files)
• create instances of that struct in your .cpp files
• you can't use variables from one .cpp file in another (unless you use extern - but you'll hardly ever need that)

Let's give an example:

label.h:
#ifndef LABEL_H#define LABEL_Hclass Label{public:	Label(std::string text, int x, int y, float r, float g, float b);		// Instead of directly exposing these variables,	// consider making them private, and adding a draw() function	// or something similar.	// char*'s are C-style strings. std::string is the C++ approach.	// For formatting, you can look into std::stringstream.	std::string text;	// if you had a Point2D class, you could say: Point2D position;	int x;	int y;	// if you had a Color class, you could say: Color color;	float r;	float g;	float b;};#endif

label.cpp
#include "label.h"Label::Label(std::string text, int x, int y, float r, float g, float b)	: text(text), x(x), y(y), r(r), g(g), b(b)	// If the above syntax looks weird: it's an initializer list.	// It initializes the member variables with the arguments you	// passed. It's no problem that they all have the same names,	// as only members can be initialized.{}

camera.cpp: (why would a camera need to know about text labels?)
#include "label.h"Label title = Label("text", 15, 12, 0.8, 0.8, 0.8);

##### Share on other sites
Quote:
 Original post by Captain PTo react to your latest post, you've made several mistakes. Here's what to do:place the struct definition in the header file, do not create instances of it there (that will cause all files that include that header to get their own 'title' and 'projectname' variables!)add inclusion guards to the header (otherwise you'll get double definitions when you include the header into multiple other files)create instances of that struct in your .cpp filesyou can't use variables from one .cpp file in another (unless you use extern - but you'll hardly ever need that)Let's give an example:label.h:*** Source Snippet Removed ***label.cpp*** Source Snippet Removed ***camera.cpp: (why would a camera need to know about text labels?)*** Source Snippet Removed ***

My camera class contains all the information on the frame interval and the location of things on screen. This is useful for the compass and the markers on the screen.

I must admit I'm fairly new to OOP. So far i've managed to fit everything in simple functions. I will need to learn this first before continuing work on my project.

Thanks for both the replies, they are very clear.

##### Share on other sites
Quote:
 Original post by DefeatistYes! This is exactly what Im looking for. So far it works from one file. How can I forward declarate said struct so I can store things in it from elsewhere?

0) You can't construct a string like that. printf() is a very special function that takes varying numbers of arguments. The work of interpreting a format string and inserting values is done inside printf(), not at the call site as some kind of language feature.

To "assemble" strings in C++, you can use the std::stringstream class. You should also be using the std::string class to represent text.

1) Don't use global instances of the struct. Create instances when you need them. For example:

#include <string>#include <sstream>uiMsg title;std::stringstream ss;ss<< "Current Frames Per Second: " << int(framesPerSecond);title.msgText = ss.str();title.x = 15;title.y = 12;title.fR = .8;title.fG = .8;title.fB = .8;draw(title);

2) Use constructors to make your life simpler. Also consider organizing the structure hierarchically. Thus you could have something like

#include <string>#include <sstream>Message title;std::stringstream ss;ss<< "Current Frames Per Second: " << int(framesPerSecond);draw(uiMsg(ss.str(), Position(15, 12), Color(.8, .8, .8)));

Alternatively, maybe the containing structure isn't so useful:

#include <string>#include <sstream>Message title;std::stringstream ss;ss << "Current Frames Per Second: " << int(framesPerSecond);draw(ss.str(), Position(15, 12), Color(.8, .8, .8));

It would be useful if you have to store the message - e.g. in a data member of some other class:

#include <string>#include <sstream>Scene scene;// ...Message title;std::stringstream ss;ss << "Current Frames Per Second: " << int(framesPerSecond);scene.addMessage(ss.str(), Position(15, 12), Color(.8, .8, .8));// ...scene.drawAllMessages();void Scene::addMessage(const std::string& s, const Position& p, const Color& c) {  messages.push_back(Message(s, p, c));}void Scene::drawAllMessages() {  std::for_each(messages.begin(), messages.end(), draw);}

3) The actual problem with your code organization is that you need the actual struct definition to be in the header. Otherwise, camera.cpp knows that 'uiMsg' is a struct, but it doesn't know what the struct contains, so you can't write code there that manipulates the contents.