-1

A lot of times the answer is merely when I want things to be allocated on a stack instead of the heap.. assuming I dont know what the stack and the heap are (and please dont try to explain it here), when exactly should I be using structs instead of classes?

Here is the answer I've been giving out, but please tell me if I'm wrong or falling short of a better answer:

I create structs usually when I have enums that I want to add more data to. For instance, I might start with a simple enum:

public enum Colors { Blue, Green, Red }

Then if I need to store more aspects of this data I go to structs:

public struct Color
{
    string Name;
    int HexValue;
    string Description;
}

public class Colors
{
    public static Color Blue;
    public static Color Red;
    public static Color Green;
    static Colors()
    {
        Blue = new Color("Blue", 1234, "A light blue"
    }
}

The point is... similar to enums, I use structs just when I want to declare a bunch of types.

thorn0
  • 9,362
  • 3
  • 68
  • 96
djmc
  • 853
  • 9
  • 20

8 Answers8

7

struct vs class in .NET

The real time to use a struct is when you want value type like properties. Value types behave very differently from reference types, and the difference can be shocking and bug inducing if you aren't aware. For example a struct is copied into (and out of) method calls.

The heap vs stack isn't a compelling argument to me. In a typical .NET app, how often do you care about where the object lives?

I very rarely use structs in .NET apps. The only place I've truly used them was in a game where I wanted value type like properties for objects like vectors and such.

struct vs class in C++

This is a much simpler question to answer. structs and classes in C++ are identical to each other with only one minor difference. Everything in a C++ struct is public by default, where as everything in a C++ class is private by default. That is the only difference.

Matt Greer
  • 60,826
  • 17
  • 123
  • 123
  • +1 for actually answering the question (for C#), or rather, naming a difference that doesn't depend on a whim of the VM. Value type semantics can be useful/desirable from time to time, just be sure you realize the difference. –  Dec 02 '10 at 17:01
  • @Matt: It's not quite the only difference -- *inheritance* in C++ is public by default for structs, and private by default for classes. – Stuart Golodetz Dec 02 '10 at 17:05
  • @sgolodetz: base classes are "things", hence "everything is public by default" includes base classes :-) – Steve Jessop Dec 02 '10 at 17:12
  • @sgolodetz, I'm pretty sure that inheritance can be considered to fit into the set of "everything", so @Matt has included your point. @Matt, funnily the very few times I have cared about where an object lives in .NET I've cared about structs being physically together in the heap when in an array - a situation where they aren't on the stack at all. The stack vs heap thing does have its value in micro-opts, but it's a pretty minimal value. It does go hand-in-hand with copy-by-value though (assuming a stack/heap based implementation in the first place). – Jon Hanna Dec 02 '10 at 17:14
  • @Steve: :) Everything *in* a C++ struct... Base sub-objects are *in* derived objects in some sense, but base classes aren't *in* derived classes. – Stuart Golodetz Dec 02 '10 at 17:14
  • (I am nitpicking a lot though :) Don't mind me...) – Stuart Golodetz Dec 02 '10 at 17:16
  • Yeah, I'm nitpicking differently - the fact that X derives from Y is "in" X's definition. – Jon Hanna Dec 02 '10 at 17:20
  • @Jon: And "X's definition" is not "X" (arguable from a philosophical standpoint) :) Ok, but more seriously -- the fact that inheritance is public by default for structs and private by default for classes is not obvious from what was originally said, and is reasonably worth knowing. I had already upvoted the original answer (it's good), but I still think the point is worth a mention, even just in a comment -- the C++ FAQ (http://www.parashift.com/c++-faq-lite/classes-and-objects.html#faq-7.9) also distinguishes between members and base classes in this case, for what it's worth. – Stuart Golodetz Dec 02 '10 at 17:28
  • I think we all know life is too short to go on about this though -- I'm happy to agree to disagree... – Stuart Golodetz Dec 02 '10 at 17:33
  • @sgolodetz yes, especially since while I disagree with you in including inheritance in "everything", I do agree with you that it's worth pointing it out separately. – Jon Hanna Dec 06 '10 at 09:43
4

Simplistically, structs are for data, classes are for data and the manipulations of those data.

KevinDTimm
  • 14,226
  • 3
  • 42
  • 60
1

well in C++ land, you can allocate a struct (or class) on the stack or the heap... I generally use a struct when the default public access to everything is useful and class when I want to encapsulate... I also use structs for functors that need state.

Nim
  • 33,299
  • 2
  • 62
  • 101
  • 2
    structs and classes in C++ are almost identical. In .NET however, they are very different from each other. – Matt Greer Dec 02 '10 at 16:58
  • Ah sorry, I didn't see the C++ tag. – Matt Greer Dec 02 '10 at 16:59
  • @Matt: The question is misguided -- the OP is asking about two completely different things at the same time. – Stuart Golodetz Dec 02 '10 at 17:01
  • 1
    @Matt Greer, by .NET do you mean c#? or managed C++? I'd have thought that even in managed C++ they behave identically to normal C++? (I don't have much .NET experience!) Either ways, I did qualify my answer with "well in C++ land" ... :) – Nim Dec 02 '10 at 17:02
  • I have no real experience with Managed C++. Structs vs classes in Managed C++ is an interesting question. – Matt Greer Dec 02 '10 at 17:03
1

In C++, technically it doesn't matter. You could use struct for polymorphic object and class for PODs. The language wouldn't care, though your coworkers may plot a bloody revenge. Aside from default access, there's no difference between class and struct.

Ultimately, the most important consideration is that you pick a coding style, and apply it consitantly. Maybe that means everything is classes, or maybe PODs are structs. You need to decide for yourself, taking in to consideration any coding practices applied by whomever you work for.

As for myself, I only use structs if the object has only public members and no virtuals. They might have data only or data and methods. Typically I use structs for buckets of data that may or may not have simple operations associated with them, usually to convert from one type to another. Hence they may also have constructors.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • +1, but the coworkers in question need to find something better to do I think :) – Stuart Golodetz Dec 02 '10 at 17:02
  • 1
    Those coworkers should also remember that it's hard to write code that will break if a class you're relying on switches from `class` to `struct` or vice-versa, as long as it updates access specifiers so that it doesn't change the accessibility of any of its members. It can break the ODR if you've c'n'p'ed the definition, but aside from that nobody should care much whether something is defined `struct` or `class`. It's a handy clue, but if your class is guaranteed to be POD, for heaven's sake *document* that, especially in John's case where `struct` doesn't necessarily mean POD anyway :-) – Steve Jessop Dec 02 '10 at 17:18
  • @Steve: Right, I didn't mean to imply that my structs are all PODs – John Dibling Dec 02 '10 at 17:20
  • .. and when I say "aside from that", I'm not actually advocating doing that c'n'p. It sort of happens though if you relink without recompiling. I doubt that ODR violation would trouble most implementations, but you never know. – Steve Jessop Dec 02 '10 at 17:21
  • sure. Something you occasionally hear from others is "use struct for POD, class for non-POD", which I don't much like because I'm not actually convinced that everyone always accurately knows whether a class is POD or non-POD anyway, so I always suspect that such a rule will lead to mistakes. Better to provide guarantees like that some other way. `struct` for "all public" I like, that has the virtue that it doesn't actually matter if you get it wrong, or add private members later :-) And adding the first virtual function to a class is a disruptive change anyway, so no harm there either. – Steve Jessop Dec 02 '10 at 17:28
1

You have this labelled with C#, C++ and "language-agnostic". The fact is though, the difference between structs and classes in C# and C++ are completely different, so this is not a language-agnostic question.

In C++ class is syntactic sugar for struct with different default visibility. The reason is that C had a struct and only had "public" visibility (indeed, it's not even a fully meaningful statement in C, there's no such thing as OO-style information hiding in C).

C++ wanted to be compatible with C so it had to keep struct default to everything visible. C++ also wanted to follow good OO rules, in which things are private by default, so it introduced class to do exactly the same, but with different default visibility.

Generally you use struct when you are closer to C-style use; no or relatively simple member functions (methods), simple construction, ability to change all fields from the outside ("Plain Old Data"). class is generally used for anything else, and hence more common.


In C# a struct has value semantics while a class has reference semantics (in C++ both classes and structs have value semantics, but you can also use types that access them with reference semantics). A struct, as a value-type is self-contained (the variable contains the actual value(s) directly) while a class, as a reference type refers to another value.

Some other differences are entailed by this. The fact that we can alias reference types directly (which has both good and bad effects) comes from this. So too do differences in what equality means:

A value type has a concept of equality based on the value contained, which can optionally be redefined (there are logical restrictions on how this redefinition can happen*). A reference type has a concept of identity that is meaningless with value types (as they cannot be directly aliased, so two such values cannot be identical) that can not be redefined, which is also gives the default for its concept of equality. By default, == deals with this value-based equality when it comes to value types†, but with identity when it comes to reference types. Also, even when a reference type is given a value-based concept of equality, and has it used for == it never loses the ability to be compared to another reference for identity.

Another difference entailed by this is that reference types can be null - a value that refers to another value allows for a value that doesn't refer to any value, which is what a null reference is.

Also, some of the advantages of keeping value-types small relate to this, since being based on value, they are copied by value when passed to functions.

Some other differences are implied but not entailed by this. That it's often a good idea to make value types immutable is implied but not entailed by the core difference because while there are advantages to be found without considering implementation matters, there are also advantages in doing so with reference types (indeed some relating to safety with aliases apply more immediately to reference types) and reasons why one may break this guideline - so it's not a hard and fast rule (with nested value types the risks involved are so heavily reduced that I would have few qualms in making a nested value type mutable, even though my style leans heavily to making even reference types immutable when at all practical).

Some further differences between value types and reference types are arguably implementation details. That a value type in a local variable has the value stored on the stack has been argued as an implementation detail; probably a pretty obvious one if your implementation has a stack, and certainly an important one in some cases, but not core to the definition. It's also often overstated (for a start, a reference type in a local variable also has the reference itself in the stack, for another there are plenty of times when a value type value is stored in the heap).

Some further advantages in value types being small relate to this.

Therefore in C# a struct when you are solely concerned with value-semantics and will not want to alias (string is an example of a case where value-semantics are very important, but you would want to alias, so it is a class to make it a reference-type). It's also a very good idea for such types to be immutable and an extremely good idea for such types to have fields that total to less than 16bytes - for a larger struct or a struct that needs to be mutable it may well be wise to use a class instead, even if the value-semantics make struct your first choice.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
1

When to use struct...

  • When you want object to behave as a value type
  • When the required size of object is <=16 bytes roughly.
Manish Basantani
  • 16,931
  • 22
  • 71
  • 103
0

A struct is actually exactly the same thing as a class - with one difference: in a class, everything is private by default while in a struct, everything is public by default!

struct Color
{
    string Name;
private:
    int HexValue;
};

would be the same as

class Color
{
    int HexValue;
public:
    string Name;
};
w8p
  • 24
  • 1
0

I would say , use stack when your data is smaller in size and you don't want a few thoushands of this object because it can hurt ou back a lot because as already mentioned that value types are copied by nature so pasing few thoushands of objects which is copied by value is not a good idea also.

Second point , i would like to include is when you only want data for most of the time and data is numeric most of the time , you can use stack.

TalentTuner
  • 17,262
  • 5
  • 38
  • 63