December 2017

Sun Mon Tue Wed Thu Fri Sat
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
My Photo

« PSYCHOLOGY - physical beauty | Main | MY LIFE - some politics »

December 16, 2003

Comments

Bman

What didn't you know you could do? Initialize a structure with a reference? Sure you can. If you didn't initialize it there, you'd be stuck with a bad reference (in theory anyway).

seeker

I'm thinking he meant using a '.' to dereference. It's one of those things C++ give you to trip you up. Bad for maintainability, imho.

Raist3d

Ok, I guess that was a tad confusing. What I meant was two things:

1. what Bman pointed out. I just haven't done it. I thought it required some constructor initialization crap.

2. that memory wise it's really all the same to compiled code. #2 is just because I thought for a while there was something else going on for references and I never bothered to really dig down to what was going on.

Looking at it now, it's all obvious, it just didn't occur to me right away that's all.

Paul Reynolds

Perhaps I'm stating the obvious but... That struct initialization is the old school C style. You can't do that with a class (and you thought default member permissions was the only difference between structs and classes!). That said, it's sort of fragile in that it's assuming the order of your members. So if you change the struct member variables, you're either going to have a broken build or rogue data placement.

But it's always cool to actually take the time and see what's going on under the hood!

crowdpleazr

Yeah, Paul is right. You can create ctors for structs as well as objects, so you're better off not intializing it that way (remember, structs are like objects without inheritence and where all members are default public scope). The only difference is this:

tTest myTest(myA, &myA);

where then you have to create a ctor for your struct that does this:

tTest(A &newRef, A *newP)
:r(newRef)
,p(newP)
{
}

And yeah, references are exactly like pointers, same size and all, they're just a nicer way for some people to look at code because you can use the dot operator instead of the arrow. About the only thing you can't do is delete the memory directly using the reference, so it's sort of a way to protect that from happening. Sort of.

Paul is right though, you can't ever assume that the reference and the pointer point to the same data in your struct.

Raist3d

Hey (Paul & Crowd) thanks for pitching in.

Crowdplezr, the contructor form is what I expected I *had* to do (i.e. not just a convention but that I had to do it).

One additional comment:

"(remember, structs are like objects without inheritence and where all members are default public scope). "

Actually structs can have inheritance from other structures. So this is valid:

struct A { int x ; };

struct B : public A { int y ; } ; // just a blah example

Paul makes the interesting note that this initialization (the one I mentioned) is another difference between structs and classes, which as he says I expected there was no difference between them, except for the public default scope.


Thanks for the comments.


Raist3dd

"Perhaps I'm stating the obvious but... That struct initialization is the old school C style. You can't do that with a class (and you thought default member permissions was the only difference between structs and classes!)."

I knew there was something that was bugging me about this... (the last sentence, not the first, but one caveat in a sec):

Yes, classes and structures are the same and you can also initialize a class this way - as long as you don't make it an "un-aggregated" type by virtual functions, private, etc.

So yes this would work:

class A
{
public:
int x,y;
};

A myA = { 3, 3 };

And conversely, this would not work:

struct B
{
public:
int x;
private:
float z;
};

B myB = { 3, 3.0f };

So C++ is still consistent on the classstructure equivalence.

Now the caveat on initialization:

If you have some data sitting somewhere ( I realize if you have this you should be loading it form somewhere) and you do the constructor type initialization you will now have:

Twice the data (if you needed a copy of the data and modify the copy, and needed to keep the original data this is a non issue then)

A constructor function call.

Now, if you don't need to modify the data (some constant structure instance or such) now you have twice the data, because it will haved the orginal data, code to copy it and now the copy in the instance.

Raist3dd

Update:

Nope, I was wrong on the double data. I was seeing data duplicated but in non-optimized compiled code. When it's optimized the compiler won't do such a thing. Cool. It's only in non-optimized code where it will duplicate it.

Anyway, it's good to know anyhow. I could imagine someone trying to do a debug build and running into memory problems if trying to fit it in a certain space, although that should be a suggestion to load from a file.

Paul Reynolds

Yep, a struct with a vtable can't be initialized that way. I always associated it with structs. Interesting.

Yes, load data chunks from a file! One of my pet peeves is tools that generate source code. :o)

Raist3dd

And yet another update (gee!) on what I said (found something new):

If you use the copy constructor deal, and this guy is either not defined locally to the variables in a module you are defining of that type, or the constructor is not defined in the header, you will be screwed, the compiler will generate duplicate data regardless of O level.

So in other words, if the constructor is a declaration with external linkage (i.e. the initialization list only shows up in its corresponding .cpp module), then yup, you will get duplicate data and more code to boot. Makse sense also.

Man...

- Raist

The comments to this entry are closed.