Forum Topic: C++: Structs and Custom Functions

(408 views • 11 replies)

This topic is 1 page long.

<< < > >>
None

blah569

Reply To Post Reply & Quote

Posted at: 1/6/08 06:27 PM

blah569 DARK LEVEL 21

Sign-Up: 01/18/05

Posts: 2,697

C++: Main

I know that there was already a tutorial on structs, but I wanted to make my own, and go in with some other aspects of C++. First of all, you may ask yourself, why would I want to use structs? Structs are very useful in games. A struct is a point in your C++ file inwhich you may prepare a huge list of variables. Let us take a quick preview of an example struct:

struct stats
{
	int health;  //Here we prepare a simple health variable.  Notice that the type of the variable is an "integer."
	int level;  //Here we prepare a simple level variable.  Also notice, the type of the variable is an "integer."
	int exp;  //Here we prepare a simple experience level.  Once again, notice that the type of the variable is an "integer."
};  //When closing a struct, instead of the traditional closing curley bracket, you have that, as well as a semi-colin, so it flows together as "};."

Now, reviewing that struct, as you can see, it is just a very simple struct. Now, let us take a look at a simple C++ program using structs.

//Here we include all of the header files for the application.
#include <iostream>

//Here we prepare all of the name spaces.
using namespace std;  //We need this name space for most console functions, so instead of typing std::cout << "Hello, World!" << endl; we can type cout << "Hello, World! " <<endl;

//Here we setup the structs for in-app use.
struct stats
{
	int health;
	int level;
	int exp;
};

//Here we setup all of the variables for in-game use.
stats player;
stats enemy;

//Here is the main program loop.
void main(){
	player.health = 100;
	player.level = 1;
	player.exp = 10;
	
	enemy.health = 110;
	enemy.level = 2;
	enemy.exp = 30;

	cout<<"Welcome to my program!  The stats are:\n-------------------------------------------------------\nPlayer Health:  " << player.health << "\nPlayer Level:   " << player.level << "\nPlayer EXP:     " << player.exp << "\n-------------------------------------------------------\nEnemy Health:   " << enemy.health << "\nEnemy Level:    " << enemy.level << "\nEnemy EXP:      " << enemy.exp << "\n-------------------------------------------------------\nPress enter to exit the application. \n-------------------------------------------------------" << endl;
	cin.get(); //Here we pause output until the user preses a generic key.

	return; //Here we use "return;" to return out of the program loop.  If we were using "int main(){" instead of "void main(){," we would use return 0; instead of return;
}

If you can not stand that cout line, here it is again, but with more line drops:

//Here we include all of the header files for the application.
#include <iostream>

//Here we prepare all of the name spaces.
using namespace std;  //We need this name space for most console functions, so instead of typing std::cout << "Hello, World!" << endl; we can type cout << "Hello, World! " <<endl;

//Here we setup the structs for in-app use.
struct stats
{
	int health;
	int level;
	int exp;
};

//Here we setup all of the variables for in-game use.
stats player;
stats enemy;

//Here is the main program loop.
void main(){
	player.health = 100;
	player.level = 1;
	player.exp = 10;
	
	enemy.health = 110;
	enemy.level = 2;
	enemy.exp = 30;

	cout<< "Welcome to my program!  The stats are: " << endl;
	cout<< "-------------------------------------------------------" << endl;
	cout<< "Player Health:  " << player.health << endl;
	cout<< "Player Level:   " << player.level << endl;
	cout<< "Player EXP:     " << player.exp << endl;
	cout<< "-------------------------------------------------------" << endl;
	cout<< "Enemy Health:   " << enemy.health << endl;
	cout<< "Enemy Level:    " << enemy.level << endl;
	cout<< "Enemy EXP:      " << enemy.exp << endl; 
	cout<< "-------------------------------------------------------" << endl;
	cout<< "Press enter to exit the application." << endl;
	cout<< "-------------------------------------------------------" << endl;
	cin.get(); //Here we pause output until the user preses a generic key.

	return; //Here we use "return;" to return out of the program loop.  If we were using "int main(){" instead of "void main(){," we would use return 0; instead of return;
}

I personally prefer to use a single line then multipul lines, but whatever suits your needs. Encase you do not know, "\n" is a new line, as well as "endl;"

The above block compiled perfectly using Microsoft Visual C++ 2008.

Now, I will talk about custom functions. Go ahead and made a new header file. I will call mine "customfunctions.h." You may call it whatever you wish, but it is not a good idea to call it "functions.h," as there already may be a header file in your IDE (If you are using one), and you may have name conflicts.

Inside of your "customfunctions.h," (or whatever you called it), add this block:

#include <iostream> //Our major header file we need to use for consoles.

using namespace std;  //Our "std" name space we need to use to shorten lines.

//On to the functions:

void simpleAddition(int num1, int num2){
	cout << num1 + num2;
	return;
}

//The above makes a function entitled "simpleAddition," with two prameterers, "num1" and "num2."  The program will add both priamters.
//We use return; to continue on with your program.

Now, make a "main.cpp" file. Inside of your main.cpp file, add this.

//Here we prepare the header files we need to use.
#include "customfunctions.h"
//We only need to include "customfunctions.h," as it already has iostream and the namespace prepared inside of it.

//Here we prepare the struct for use:
struct mathTest
{
	int number1;
	int number2;
};

//Here we prepare the variables for use.
mathTest numbers;

//Here is the program loop.
void main(){
	numbers.number1 = 2;
	numbers.number2 = 2;

	cout<< "The answer to " << numbers.number1 << " + " << numbers.number2 << " is ";
		simpleAddition(numbers.number2, numbers.number2);
	cout<< "." <<endl;
	cout<< "Press enter to exit the application." <<endl;
	cin.get();

	return;
}

That compiled perfectly using Microsoft Visual C++ 2008.

I really do not think that there is anything else to go over. I hoped you learned something in this tutorial. Opinions?

PHP: Main | AS3: Main | Get Firefox | Host large files (fast and free)!
"Thank you for learning me English."

BBS Signature

None

TheRyoku

Reply To Post Reply & Quote

Posted at: 1/6/08 06:35 PM

TheRyoku NEUTRAL LEVEL 09

Sign-Up: 11/08/07

Posts: 780

Not bad, always wondered about including your own header files, pretty good tutorial, it's just really basic. Anyway, I like the custom functions, and how they work, seems to work nicely, thanks Blah :D


None

phyconinja

Reply To Post Reply & Quote

Posted at: 1/6/08 07:23 PM

phyconinja EVIL LEVEL 25

Sign-Up: 09/18/04

Posts: 2,825

Just because it bothers me.

At 1/6/08 06:27 PM, blah569 wrote: simpleAddition(numbers.number2, numbers.number2);

None

Cinjection

Reply To Post Reply & Quote

Posted at: 1/6/08 09:23 PM

Cinjection LIGHT LEVEL 18

Sign-Up: 04/06/04

Posts: 2,486

The structs that you're talking about are POD C-style structures. It should be noted that structures in C++ allow you to do anything you can do with a class. That is, you can have methods, constructors, and other such OOP goodies. The only real difference between a class and a struct in C++ is that a class's members are private by default and struct's members are public by default.

The best part about going on Newgrounds is that no one know that you're naked!
[My Coder Profile]

BBS Signature

None

blah569

Reply To Post Reply & Quote

Posted at: 1/6/08 09:45 PM

blah569 DARK LEVEL 21

Sign-Up: 01/18/05

Posts: 2,697

At 1/6/08 07:23 PM, phyconinja wrote: Just because it bothers me.

At 1/6/08 06:27 PM, blah569 wrote: simpleAddition(numbers.number2, numbers.number2);

Oopps, lol. I didn't catch that.

PHP: Main | AS3: Main | Get Firefox | Host large files (fast and free)!
"Thank you for learning me English."

BBS Signature

None

methinkso

Reply To Post Reply & Quote

Posted at: 1/7/08 03:29 PM

methinkso LIGHT LEVEL 07

Sign-Up: 08/31/04

Posts: 73

It is a very bad idea to define a function in a header file like that. If you included "customfunctions.h" in two different source files and linked those files together, the linker will yell at you with function redefinition errors.

Also, there's no such thing as "custom functions" in C++, and I honestly can't figure out what you're implying with the word "custom," either. You shouldn't make up terminology in a basic level tutorial (especially when it's part of your main topic) because it'll confuse people.


None

authorblues

Reply To Post Reply & Quote

Posted at: 1/7/08 05:42 PM

authorblues FAB LEVEL 12

Sign-Up: 06/21/05

Posts: 6,360

At 1/7/08 03:29 PM, methinkso wrote: It is a very bad idea to define a function in a header file like that. If you included "customfunctions.h" in two different source files and linked those files together, the linker will yell at you with function redefinition errors.

idiot. thats the reason that people use macro definitions to prevent multiple inclusion. or, if you actually know what youre doing instead of just following ten year old tutorials, youd know about

#pragma once

GENERATION 1-i: The first time you see this, copy it into your sig on any forum. Square it, and then add i to the generation.

BBS Signature

None

henke37

Reply To Post Reply & Quote

Posted at: 1/8/08 06:25 AM

henke37 NEUTRAL LEVEL 23

Sign-Up: 09/10/04

Posts: 3,607

And that it does not work in all compilers.

Each time someone abuses hittest, God kills a kitten. Please, learn real collision testing.


None

dELtaluca

Reply To Post Reply & Quote

Posted at: 1/8/08 06:28 AM

dELtaluca LIGHT LEVEL 20

Sign-Up: 04/16/04

Posts: 5,553

At 1/8/08 06:25 AM, henke37 wrote: And that it does not work in all compilers.

but you can use

#ifndef NAMEOFHEADER_HEADER_HPP etc.
#define NAMEOFHEADER_HEADER_HPP etc.

...contents of header file

#endif

which will work on all compilers, and be pretty sure you aren't going to get conflicts

My social worker says im special!

BBS Signature

None

DougyTheFreshmaker

Reply To Post Reply & Quote

Posted at: 1/8/08 07:17 AM

DougyTheFreshmaker NEUTRAL LEVEL 02

Sign-Up: 07/30/07

Posts: 519

It is a very bad idea to define a function in a header file like that. If you included "customfunctions.h" in two different source files and linked those files together, the linker will yell at you with function redefinition errors.

Guys, he's exactly right. You should know better.

First, the pragma stuff isn't standard, as mentioned. I think it's supported in most cases anyway. I'm not sure what advantages it has over include guards (besides less typing), but I stick with include guards usually. Personal preference, I guess.

Second, "if you included 'customfunctions.h' in two different source files and linked those files together, the linker will yell at you with function redefinition errors" is absolutely correct, regardless of whether or not you use include guards. If you define (NOT declare, which is usually okay) a function in a header file, you ARE asking for trouble in most cases. Usually not when you're dealing with templates (in fact they need to be defined in header files), but that has to do with the way their function bodies are written at compile time. ANYWAY, take the following three files:

foo.h

#ifndef FOO_H
#define FOO_H

#include <iostream>

void foo() { std::cout << "Foo" << std::endl;}

#endif

bar.cpp

#include <iostream>
#include "foo.h"

void bar() { std::cout << "bar" << std::endl; }

main.cpp

#include <iostream>
#include "foo.h"

int main(int argc, char *argv[]) { std::cout << "Blah" << std::endl; }

and the resulting error when you try to compile them:

Linking...
bar.obj : error LNK2005: "void __cdecl foo(void)" (?foo@@YAXXZ) already defined in main.obj
C:\C++ Projects\quicktests2\Debug\quicktests2.exe : fatal error LNK1169: one or more multiply defined symbols found

And note that bar isn't even used anywhere.

This happens because there are two translation units to compile (foo.h+bar.cpp and foo.h+main.cpp... you can think of foo.h being 'pasted into' the cpp files). The foo.h+bar.cpp combo compiles, mangles up foo and comes up with the symbol ?foo@@YAXXZ. The same thing happens with foo.h+main.cpp. Then when they're linked together, the linker sees that there are two identical symbols and flips out. The functions are the same in this case, but they COULD be different... so rather than figure out which function to pick, linking just aborts.

This doesn't happen when you simply prototype functions in header files... prototyping/declaring functions is really just a hint to the compiler that the function does, in fact, exist somewhere (the linker will figure out where exactly). No symbol is generated in that case so you can declare a function in as many translation units as you want. When it comes to linking time, though, the linker needs to find exactly one symbol for that function. If it finds any more or less than one symbol, compilation will fail.

We should take care not to make the intellect our god; it has, of course, powerful muscles, but no personality.
Freshmaking
Brainscrape

BBS Signature

None

methinkso

Reply To Post Reply & Quote

Posted at: 1/9/08 03:15 AM

methinkso LIGHT LEVEL 07

Sign-Up: 08/31/04

Posts: 73

At 1/7/08 05:42 PM, authorblues wrote:
At 1/7/08 03:29 PM, methinkso wrote: It is a very bad idea to define a function in a header file like that. If you included "customfunctions.h" in two different source files and linked those files together, the linker will yell at you with function redefinition errors.
idiot. thats the reason [. . .]

See Dougy's post.

Before you start throwing insults and calling someone an idiot, you should actually know what the hell you're talking about.


None

authorblues

Reply To Post Reply & Quote

Posted at: 1/9/08 06:50 PM

authorblues FAB LEVEL 12

Sign-Up: 06/21/05

Posts: 6,360

At 1/9/08 03:15 AM, methinkso wrote: Before you start throwing insults and calling someone an idiot, you should actually know what the hell you're talking about.

ill admit that i was hasty to throw around terms like "idiot", but my confusion wasnt because i was ill-informed on the subject, as your cocky attitude would suggest. it was a confusion of terminology. i was under the impression we were referring to using macro includes, but i managed to miss the distinction about "linking files".

ill ask that you not be so hasty, to assume i know nothing, when you get cocky.

GENERATION 1-i: The first time you see this, copy it into your sig on any forum. Square it, and then add i to the generation.

BBS Signature

All times are Eastern Standard Time (GMT -5) | Current Time: 11:45 AM

<< Back

This topic is 1 page long.

<< < > >>
You need a Grounds Gold Account to post on the NG BBS! If you don't have one, click here to sign up now! It's fast, free, and easy — and opens up tons of great NG features!