Page 1 of 1
Structs? Unions? Classes?
Posted: Sun Feb 02, 2014 4:06 pm
by corey__cakes
I have a question relating to classes, structs, and unions. What is the difference? I have a trendy C++ reference book that states that the only difference between them is that members are default private, public, or protected depending on what you use. So I'm guessing that means they're interchangeable. Then why do trendier programmers than me use structures more often then I do? Why don't they use classes for everything?
Thanks for any and all responses.
Re: Structs? Unions? Classes?
Posted: Sun Feb 02, 2014 4:39 pm
by Nokurn
classes and structs are very similar. unions are entirely different from both.
Your book is correct in that members of classes default to private, while members of structs default to public. Why not just use classes? It can be useful to give further meaning to structs for the sake of organizing your code. These meanings are enforced only by you as a coding convention. A common meaning for struct is that it contains only data, but no methods.
The only real similarity a union has to a class or struct is that it introduces a new type to the scope. Beyond that, it's completely different. A union is defined in a similar fashion to a struct, and its "members" can be accessed using the same syntax, but the key difference is that a union's members occupy the same memory. If you have a union with 3 members (a char, an int, and a void*), the union will be sizeof(void*) (which could be 4 or 8 bytes depending on if you're compiling 32- or 64-bit code), or the maximum size of any member. If you set the void*, then read the char or int, you will receive some portion of the void* as a char or int. If you set the char to 'A', one of the bytes of the void* and int will be set to 'A'.
Generally speaking, if you don't know what a union is, you don't need to use it. You probably still shouldn't use it even if you do know what it is unless you have a very good reason to. Its use-cases are pretty specific and typically fall outside of a newer programmer's scope.
Re: Structs? Unions? Classes?
Posted: Sun Feb 02, 2014 4:50 pm
by Falco Girgis
I tend to use structs for small, simple, value-only aggregate data types. For things like a simple vector or matrix, you might as well just keep it public as a struct instead of wasting time writing accessors just for the sake of being a good little OO-whore.
This also shows the OO-whores that you chose a structure specifically, because you had intended to not bother with data encapsulation... It looks less like you're being OO-negligent and more like you knew damn well what you were doing.
A union on the other hand is completely different than the other two. The members of a union all share the same memory location, meaning only one of the members can be valid at a time.
It's efficient for resource-sensitive applications, and it offers syntactic sugar for C/++ pointers, where you can reference an object through a base or polymorphic parent pointer type through the same address (assuming there is no vtable offset).
Re: Structs? Unions? Classes?
Posted: Sun Feb 02, 2014 10:36 pm
by corey__cakes
Yea, Access functions are a pain to write for every object.
Re: Structs? Unions? Classes?
Posted: Mon Feb 03, 2014 6:15 am
by James Evesque
Getters and Setters are just an interface, and have a place. That does not mean you have to use them everywhere, but doing so is considerd good practice; If for no other reason that if you must change anything, the logic is all in the function/method calls.
I don't always have access to a class keyword, but I still use getters and setters when it makes sense.
Re: Structs? Unions? Classes?
Posted: Sun Mar 16, 2014 4:11 pm
by short
Something to think about, I'm a huge fan of immutability. Instead of encoding your data by 'setting' the data members of a struct directly, make those values of your struct const -- meaning readonly. Have the user (you) pass in all the values into the struct's constructor so you can initialize the data members and be guaranteed they never change. (For structs with reasonable defaults, see the builder pattern. The builder is a class, with mutable data, but *builds* an immutable object). A silly example, consider it as if providing a constructor taking the x/y/z directly is infeasible (as is the case a lot of the time in more complex software):
Code: Select all
struct Vector {
int const x, y, z;
Vector(int const x_param, int const y_param, int const z_param) : x(x_param), y(y_param), z(z_param) {
}
}; // struct Vector
class VectorBuiler {
int x_, y_, z_;
VectorBuiler() : x_(0), y_(0), z_(0) { // these are the default values
}
VectorBuilder& with_x(int const x_value) {
x_ = x_value;
return *this;
}
VectorBuiler& with_y(int const y_value) {
y_ = y_value;
return *this;
}
VectorBuilder& with_z(int const z_value) {
z_ = z_value;
return *this;
}
Vector build() const {
return Vector(x_, y_, z_);
}
} // class VectorBuilder
// silly usage
VectorBuilder vb; // the builder is not immutable, but that's the point. The object we use *is* immutable, the vector.
Vector const v = vb.with_x(32).with_y(32).build(); // default z value is used.
// If Vector was a much more complicated class, with reasonable default values, there would be value with this approach.
// You can encode both default values and override them with this approach.
// You could extend the builder to encapsulate building a vector from a new vector, which keeps everything immutable by default.
// I think you can imagine how to implement this
Vector const v2 = vb.from_vector(v).with_x(42).with_z(37).build();
If you need to modify the data on your struct after you have constructed it, construct a new instance of your class and replace the old instance. If you notice your struct becomes more difficult to maintain because it has nested data structures, ie: a struct with a struct(s) internally, then in this instance it is time to make your struct a class. As a class this is obvious to the reader that something non-simple is occurring, and also keeps with the spirit of 'simple' data-structures being a 'struct' while anything more complex is a 'class'. This approach always gives me something to follow: try and prefer structs with const data members only, otherwise you might want to consider replacing your struct with a class, where you can encapsulate any immutable state. Mutable state is such a pain in the ass in software development.