C/C++ Struct vs Class
Asked Answered
M

7

136

After finishing my C++ class it seemed to me the structs/classes are virtually identical except with a few minor differences.

I've never programmed in C before; but I do know that it has structs. In C is it possible to inherit other structs and set a modifier of public/private?

If you can do this in regular C why in the world do we need C++? What makes classes different from a struct?

Merline answered 1/5, 2010 at 14:20 Comment(2)
possible duplicate #55085Frisian
Possible duplicate of When should you use a class vs a struct in C++?Hydropathy
D
175

In C++, structs and classes are pretty much the same; the only difference is that where access modifiers (for member variables, methods, and base classes) in classes default to private, access modifiers in structs default to public.

However, in C, a struct is just an aggregate collection of (public) data, and has no other class-like features: no methods, no constructor, no base classes, etc. Although C++ inherited the keyword, it extended the semantics. (This, however, is why things default to public in structs—a struct written like a C struct behaves like one.)

While it's possible to fake some OOP in C—for instance, defining functions which all take a pointer to a struct as their first parameter, or occasionally coercing structs with the same first few fields to be "sub/superclasses"—it's always sort of bolted on, and isn't really part of the language.

Decrepitate answered 1/5, 2010 at 14:28 Comment(6)
From OOP prospective .Net guys have defined it this way ✓ CONSIDER defining a struct instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects. X AVOID defining a struct unless the type has all of the following characteristics: 1. It logically represents a single value, similar to primitive types (int, double, etc.). 2. It has an instance size under 16 bytes. 3. It is immutable.Prosecution
@Prosecution That's the distinction between structs and classes in C#, but that's simply irrelevant to C++, and even more so to C. In C#, classes and structs are actually different; not so in C++, and C only has structs without OO.Decrepitate
wouldn't be better to have kept the same C semantic in C++ struct? and when required to use a "struct in a c++ way" just use a class? I have never got the benefit of having an "augmented" struct in C++ compared to C. I like still using struct as where designed in C, otherwise use a class, with some exception allowed.Chiquia
@Chiquia C++ structs have all the behaviours of C structs.Hunchback
@Hunchback not really as i can have private members in C++ structs for eg, also i think C99 structs have edge cases that are different from C++ whatever version, for eg initialization. apart from that C++ struct call a default constructor that is not the case in C. right?Chiquia
I'm more and more over the years using structs instead of classes. It leads to much cleaner designs in my opinion.Gymnastics
A
17

Other that the differences in the default access (public/private), there is no difference.

However, some shops that code in C and C++ will use "class/struct" to indicate that which can be used in C and C++ (struct) and which are C++ only (class). In other words, in this style all structs must work with C and C++. This is kind of why there was a difference in the first place long ago, back when C++ was still known as "C with Classes."

Note that C unions work with C++, but not the other way around. For example

union WorksWithCppOnly{
    WorksWithCppOnly():a(0){}
    friend class FloatAccessor;
    int a;
private:
    float b;
};

And likewise

typedef union friend{
    int a;
    float b;
} class;

only works in C

Argentite answered 1/5, 2010 at 15:8 Comment(1)
Using cpp keywords in your c code and then claiming it is not cpp compatible is rather stupidHepburn
P
14

I'm going to add to the existing answers because modern C++ is now a thing and official Core Guidelines have been created to help with questions such as these.

Here's a relevant section from the guidelines:

C.2: Use class if the class has an invariant; use struct if the data members can vary independently

An invariant is a logical condition for the members of an object that a constructor must establish for the public member functions to assume. After the invariant is established (typically by a constructor) every member function can be called for the object. An invariant can be stated informally (e.g., in a comment) or more formally using Expects.

If all data members can vary independently of each other, no invariant is possible.

If a class has any private data, a user cannot completely initialize an object without the use of a constructor. Hence, the class definer will provide a constructor and must specify its meaning. This effectively means the definer need to define an invariant.

Enforcement

Look for structs with all data private and classes with public members.

The code examples given:

struct Pair {  // the members can vary independently
    string name;
    int volume;
};

// but

class Date {
public:
    // validate that {yy, mm, dd} is a valid date and initialize
    Date(int yy, Month mm, char dd);
    // ...
private:
    int y;
    Month m;
    char d;    // day
};

Classes work well for members that are, for example, derived from each other or interrelated. They can also help with sanity checking upon instantiation. Structs work well for having "bags of data", where nothing special is really going on but the members logically make sense being grouped together.

From this, it makes sense that classes exist to support encapsulation and other related coding concepts, that structs are simply not very useful for.

Paralyze answered 14/10, 2016 at 16:45 Comment(1)
One other consideration is portability. structs are the most portable. They can be used by C or C++ or back and forth. They can also be unpacked in Python using the struct module, for example. If your project prioritizes being compatible with other languages, interfaces or systems, prefer struct over class. For strictly program-internal affairs, prefer class.Paralyze
D
6

It's not possible to define member functions or derive structs from each other in C.

Also, C++ is not only C + "derive structs". Templates, references, user defined namespaces and operator overloading all do not exist in C.

Dissimilate answered 1/5, 2010 at 14:22 Comment(6)
I know that the templates, etc to do not exist in C but I was not aware of the power of structs in C. So then C++ only uses structs to be 'backwards' compatible with C?Merline
Just for backwards compatibility? On a practical basis there is probably something to that, but the distinction can be a signal of intent: where I use a struct I mean a largely passive POD type of thingy.Disaster
@dmckee: For what it's worth, most STL functors (i.e. std::less) are defined as structs, not classes.Raimondo
C++ is not fully backards compatible with C. You could say that the struct keyword is an accommodation to C developers. I like the struct keyword for classes that merely hold data in an ordered fashion but not provide (much) logic themselves.Cardiff
@ypnos: See my last comment. The only difference between the two is that one's members are default public, and the other are default private.Raimondo
@Billy ONeal: Well, you could argue that STL functors are another implementation of a function pointer, which, essentially, is data ;-)) And I know of the single difference.Cardiff
E
3

One more difference in C++, when you inherit a class from struct without any access specifier, it become public inheritance where as in case of class it's private inheritance.

Evvoia answered 12/9, 2012 at 12:7 Comment(0)
B
1

C++ uses structs primarily for 1) backwards compatibility with C and 2) POD types. C structs do not have methods, inheritance or visibility.

Blague answered 1/5, 2010 at 14:29 Comment(3)
For what it's worth, most STL functors (i.e. std::less) are defined as structs, not classes.Raimondo
Note that C++ structs do have methods, inheritance, and visibility.Psoriasis
c struct can include function pointer though as type(*addr)(params);Orff
A
0

Since nobody has mentioned it yet, there is actually another difference besides the default visibility. It turns out that class and struct are actually different things in MSVC.

class Vector2;

struct Vector2 {
    double x;
    double y;
};

This is 1 symbol on most compilers, but 2 different symbols on MSVC. Just this code by itself does compile fine. However, if you try to use it in more complex scenarios you will run into errors where this does not compile on MSVC because it gets confused about the symbols.

Avow answered 5/10, 2022 at 5:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.