Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Struct vs Classes?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
31 replies to this topic

#21 KaiserJohan   Members   -  Reputation: 1241

Like
2Likes
Like

Posted 23 October 2012 - 06:22 AM

Both are used for the same thing. To group bits of data together to represent 1 thing. Like a pixel, you have red, green, blue, and alpha components.

So a 32 bit pixel would look like this:

Struct Pixel
{
byte R;
byte G;
byte B
byte A;
}

This is just a simple structuring of data, so you can keep track of all the components that come together to represent a pixel. Everything is publicly visible, just like a C style struct. You can access all members like this:

Pixel pxExampleRed;
pxExampleRed.R = 255;
pxExampleRed.B = 0;
pxExampleRed.G = 0;
pxExampleRed.A = 255;

You have to remember to assign a value to all components of your struct, otherwise they will have whatever random value was set in memory where they were allocated.

Sometimes it's nice to fill out a structure to pass to a function, instead of having a giant function call that takes up 20 lines. Windows API programming is a lot like this. You can also use a structure as to return data from a function.

Classes are a bit more complicated. Their data tends to NOT be publicly visible. Instead of accessing their data directly, you call functions that will take your input and do something with it to the object that the class is representing. They also have constructors and destructors so they can handle their own initialization and clean up.

The intent of a struct is a simple grouping of data for convenience. A class is an more complex object that can take care of itself.


Structs have constructors and destructors aswell.. they get 'random' values if you dont define them (i.e the compiler generates them), which is exactly the same for a class.

Edited by KaiserJohan, 23 October 2012 - 06:23 AM.


Sponsor:

#22 Serapth   Crossbones+   -  Reputation: 5791

Like
1Likes
Like

Posted 23 October 2012 - 07:43 AM

Structs have constructors and destructors aswell.. they get 'random' values if you dont define them (i.e the compiler generates them), which is exactly the same for a class.


I wouldn't say random. The default constructor is pretty well documented in the standard.

That leads to an interesting ( and yes, related... at least to KaiserJohan's comment ) trivia question ( and one of those C++ hand grenades in waiting ).

What will this program output and why?
#include <iostream>
int main(int agrc, char** argv)
{
int* meaningOfLife = new int;
int* meaningOfLife2 = new int();
std::cout << *meaningOfLife << " and " << *meaningOfLife2 << std::endl;
}

Edited by Serapth, 23 October 2012 - 07:45 AM.


#23 Serapth   Crossbones+   -  Reputation: 5791

Like
1Likes
Like

Posted 23 October 2012 - 08:08 AM


What will this program output and why?

#include <iostream>
int main(int agrc, char** argv)
{
int* meaningOfLife = new int;
int* meaningOfLife2 = new int();
std::cout << *meaningOfLife << " and " << *meaningOfLife2 << std::endl;
}


NULL and NULL
Nether pointer are pointing to anything.


Nope, not the answer. Here's a hint, one is a pointer to something and technically neither will return null.

#24 Brother Bob   Moderators   -  Reputation: 8621

Like
4Likes
Like

Posted 23 October 2012 - 08:38 AM

The first one will print an undefined value since the integer allocated by new int is not initialized. The second one will print zero, because the integer allocated by new int() is default initialized to zero. The parentheses syntax default initializes primitive types to zero. The same goes for members; if you explicitly default initialize a primitive member of a structure or a class in the initializer list it is initialized to zero; if you omit it from the initializer list it is left with an undefined value.

#25 Serapth   Crossbones+   -  Reputation: 5791

Like
1Likes
Like

Posted 23 October 2012 - 10:12 AM

The first one will print an undefined value since the integer allocated by new int is not initialized. The second one will print zero, because the integer allocated by new int() is default initialized to zero. The parentheses syntax default initializes primitive types to zero. The same goes for members; if you explicitly default initialize a primitive member of a structure or a class in the initializer list it is initialized to zero; if you omit it from the initializer list it is left with an undefined value.


This man gets the prize. Granted, that the prize is nothing makes winning this particular contest bittersweet at best.

#26 Washu   Senior Moderators   -  Reputation: 5465

Like
0Likes
Like

Posted 23 October 2012 - 12:07 PM


The first one will print an undefined value since the integer allocated by new int is not initialized. The second one will print zero, because the integer allocated by new int() is default initialized to zero. The parentheses syntax default initializes primitive types to zero. The same goes for members; if you explicitly default initialize a primitive member of a structure or a class in the initializer list it is initialized to zero; if you omit it from the initializer list it is left with an undefined value.


This man gets the prize. Granted, that the prize is nothing makes winning this particular contest bittersweet at best.


Technically he should say unspecified value, slightly different meaning in the context of the standard language. But yes, that is one of the "great" things about C++, something as trivial and difficult to notice in the overall context of a large set of code can have a massive difference in the behavior of the application as a whole. Such as () vs no () when allocating an object or array of objects. Its even worse in the array case:

#include <iostream>
int main() {
    int* p1 = new int[10];
    int* p2 = new int[10]();
    for(int i = 0; i < 10; ++i) {
	    std::cout<<p1[i]<<std::endl;
	    std::cout<<p2[i]<<std::endl;
    }
    delete [] p1;
    delete [] p2;
}

Which not only looks terrible, but has additional symbols just to make it even more confusing. Ahh, the joys of C++ Posted Image

Edited by Washu, 23 October 2012 - 12:07 PM.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
ScapeCode - Blog | SlimDX


#27 uart777   Members   -  Reputation: -126

Like
-6Likes
Like

Posted 23 October 2012 - 02:32 PM

Listen to KaiserJohan. He knows what he's talking about, however, he defined a 32BPP pixel incorrectly with alpha last in rightmost byte (0xAABBCC*DD*). It should be like this:

#define byte unsigned char

typedef struct {
byte a, r, g, b;
} PIXEL;

You must learn what your code converts to. My ASM programming site: http://sungod777.zxq.net/

#28 Serapth   Crossbones+   -  Reputation: 5791

Like
3Likes
Like

Posted 23 October 2012 - 03:36 PM

You must learn what your code converts to. My ASM programming site: http://sungod777.zxq.net/


No, you mustn't. In fact, you should very much do the exact opposite of this, especially when starting out.

To the OP, if I hear you are learning assembly as a first language, I am going to hunt you down and beat you with a dead mackerel.

Besides, even your example doesn't guarantee the byte order within the struct. The compiler is perfectly within it's rights and in fact, probably will, byte pad that value to get the ideal alignment.

From the C++ 03 standard:
Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).

This is completely ignoring the fact "rightmost" byte is completely relative to the system you are running on. If you insist on giving beginners bad advice, please at least make it factually correct bad advice.

Edited by Serapth, 23 October 2012 - 03:39 PM.


#29 MrDaaark   Members   -  Reputation: 3555

Like
0Likes
Like

Posted 23 October 2012 - 09:23 PM

Structs have constructors and destructors aswell.. they get 'random' values if you dont define them (i.e the compiler generates them), which is exactly the same for a class.

Yes. But he was asking about usage cases of one or the other in his follow up posts. They are a hold over for C style backwards compatibility, and they get used as such.

#30 L. Spiro   Crossbones+   -  Reputation: 14354

Like
1Likes
Like

Posted 23 October 2012 - 09:54 PM

Listen to KaiserJohan. He knows what he's talking about, however, he defined a 32BPP pixel incorrectly with alpha last in rightmost byte (0xAABBCC*DD*). It should be like this:

#define byte unsigned char

typedef struct {
byte a, r, g, b;
} PIXEL;

That is nothing but a matter of convention.
RGBA formats are just as common as ARGB. There is no right or wrong way to do it (though it is a good idea to stick with the convention used by your rendering API—that is ARGB on Direct3D and RGBA on OpenGL/OpenGL ES).
You are the same person who said C++ is for newbies, yet you yourself seem to be quite a beginner. Stop saying things as matter-of-factual when you yourself have misunderstood what the facts are.


L. Spiro

Edited by L. Spiro, 23 October 2012 - 09:57 PM.

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#31 Trienco   Crossbones+   -  Reputation: 2224

Like
0Likes
Like

Posted 23 October 2012 - 10:33 PM

Structs have constructors and destructors aswell.. they get 'random' values if you dont define them (i.e the compiler generates them), which is exactly the same for a class.


That wording is extremely misleading. The compiler doesn't "generate" anything. It would be insanely stupid to write a compiler that spends all the effort of filling uninitialized variables with random content instead of a clearly defined value like 0. Those values are random, because the existing memory content isn't touched (so technically it isn't even random). The most important exception are debug builds, if the compiler is nice to enough to fill them with (very much not random) patterns to help you track down bugs like uninitialized variables or freeing/deleting something twice.
f@dzhttp://festini.device-zero.de

#32 jbadams   Senior Staff   -  Reputation: 19409

Like
2Likes
Like

Posted 24 October 2012 - 01:32 AM

he defined a 32BPP pixel incorrectly

That's not incorrect, it's simply a different convention, and as L.Spiro says neither is really more common than the other.


Like some of the others, I would personally recommend a beginner not learn asm until they have a firm handle on programming concepts in general. It is useful to know what your code converts to, and I think most experienced programmers would benefit from such knowledge, but to a beginner trying to learn about those topics is more likely to just be confusing and might encourage an unhealthy pre-occupation with attempting to hand-optimise unnecessarily.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS