The online racing simulator
#1 - Ian.H
Passing structs to functions (C++)
Hi all..

This might sound like a bit of "n00b" question and almost embarrassing to as I'm sure I should have learnt this way before some other stuff.. but how do you pass a struct to a function for both reading / writing?

Small example snippet of what I envisage code to look like. The struct is global, not that that matters I guess.. but not sure what to put for the function args

struct _foo {
AnsiString foo, bar, baz;
} foo;

UpdateStruct(foo);

void __fastcall UpdateStruct(???) {
foo.foo = "bar";
foo.bar = "baz";
foo.baz = "foo";
}

The original 'foo' struct should now be modified with the new values for calling later in the app.

Any info appreciated



Regards,

Ian
_foo* blubb;
blubb = *foo;
function(blubb);

void function (_foo* blubb)
{
*blubb->bar = "moo";
}

edit:
not sure about the dereferencing with the -> though you might have to use that line without the *

edit2:
alternatively and a bit cleaner and nicer to read would be with a class _foo which you can access via a pointer to it

_foo* blubb;
(*blubb).bar = "moo";

or in case you dont like public variables

(*blubb).writetobar("moo");
#3 - Ian.H
Quote from Shotglass :_foo* blubb;
blubb = *foo;
function(blubb);

void function (_foo* blubb)
{
*blubb->bar = "moo";
}

not sure about the dereferencing with the -> though you might have to use that line without the *

Sweet! Thanks Shotglass

This is something I've pondered on for ages but never pushed hard enough to find a solution I guess.. I always found a "workaround".. but that made any classes I wrote less universal as I was referencing forms / datamodules from the function where the global struct resided.. this should help to clean up some of my code

I did modify it slightly. Quick test code is now as follows:

// Global struct
struct _AppData {
AnsiString appdataDir;

struct _opts {
AnsiString libRootPath;
} opts;
} AppData;

// Declaration
void __fastcall TDMod::Test(_AppData *Data);


Test(&AppData);

//---------------------------------------
void __fastcall TDMod::Test(_AppData *Data) {
Data->opts.libRootPath = "C:\\some_path\\";
ShowMessage(Data->opts.libRootPath);
}

All works as expected

Thanks again.



Regards,

Ian


EDIT (in response to your 2nd edit):
I hadn't thought about putting this data into a class rather than using a global struct. Not sure why, but makes sense. I'll look into doing this too
That was bit of a C style, passing a pointer. It works fine, but in C++ it often customary to do it like this...


void __fastcall UpdateStruct(_foo &var) {
var.foo = "bar";
var.bar = "baz";
var.baz = "foo";
}

If you call it like...
UpdateStruct(mystruct);
...you can think it similar like writing the mystruct inside the function everywhere the it reads 'var'.

It is kind of a reference to a variable (or structure) of type _foo. That is not a pointer and 'var' cannot be an 'empty' reference like pointer can be NULL. So inside the UpdateStruct function you don't have to check if var is null or not because it cannot be kind of 'null'. Otherwise you would need to make it with pointers like (if you want to be safe)...


void __fastcall UpdateStruct(_foo *var) {
if( var == NULL ){
// put some error handing here (or with exception handling etc)
}else{
var->foo = "bar";
var->bar = "baz";
var->baz = "foo";
}
}

isnt &var essentially the same as passing the pointer?
except maybe with a bit less readability for someone from a c background
References are just a safer kind of pointer. They were added to C++ to solve some of the dangers in using pointers, and as such have much stricter rules about how they are used and abused. They are less versatile, but as a rule you should to use them instead of pointers wherever possible.

http://en.wikipedia.org/wiki/Reference_(C%2B%2B)
Quote from Shotglass :except maybe with a bit less readability for someone from a c background

The reference operator exists in C...?
doesnt the opperator work differently in c?
from what i understood in c++ int& is a data type not just the normal & operator
Sorry, I was having a pleb moment and wasn't reading properly I need to stop reading the forums and using the phone, it's a bad combination

You are correct; whilst it does exist (which I thought was under dispute), you can't use it for declaring variables in C, I do apologise
Thanks again for the info and general discussion.. certrainly educational

I guess sometimes the downfall of being self-taught is not always learning things in the "correct order" and I often tend to jump into something complicated as a first task rather than sticking with the basics for a while. Pointers and references was one topic I'd pretty much glanced over and not much else, things have always just seemed to work(tm) and a lot of my learning comes from trial and error with some RTFM for reference for a particular problem, instead of studying a whole chapter.. either way, it's still fun to learn



Regards,

Ian
Quote from Ian.H :Thanks again for the info and general discussion.. certrainly educational

I guess sometimes the downfall of being self-taught is not always learning things in the "correct order" and I often tend to jump into something complicated as a first task rather than sticking with the basics for a while. Pointers and references was one topic I'd pretty much glanced over and not much else, things have always just seemed to work(tm) and a lot of my learning comes from trial and error with some RTFM for reference for a particular problem, instead of studying a whole chapter.. either way, it's still fun to learn



Regards,

Ian

I'm exactly the same. If I hadn't learned languages like this - I wouldn't have learned anything.
I agree. For me I just learn the basics, then get stuck in. I don't worry about the details until I have to. A programming language can takes years to master, so no point trying to cram it all into your head in one go.

FGED GREDG RDFGDR GSFDG