1257

In what scenarios is it better to use a struct vs a class in C++?

Tamir Vered
  • 10,187
  • 5
  • 45
  • 57
Alan Hinchcliffe
  • 12,862
  • 3
  • 18
  • 11
  • 5
    I still disagree - I approach this question semantically. Maybe there are some technical differences, but semantically, they are not. Structs are really useful for creating value types, classes are not. – Jason Bunting Sep 10 '08 at 17:22
  • 5
    In practice, most people seem to use class if they plan on having member functions, and struct if they don't. This is really just a convention, however. struct and class are actually pretty much identical, except that class defaults to private access, wile struct defaults to public access. – Laurence Gonsalves Jul 28 '09 at 03:48
  • Conventions are incredibly important (consider the impact of iterator categories, or header guards, or .cxx/.h file pairs). This answer downplays that importance, and thus is less useful than most of the others. – Tom Oct 27 '09 at 02:34
  • 1
    I wouldn't say my comment "downplays" the importance of convention. I think it's important to know what's convention and what's really part of the language if you want to be more than just a cargo-cult programmer. – Laurence Gonsalves Oct 30 '09 at 04:42
  • 1
    I find that I rarely use struct in C++, except when I need auto aggregate initialization of Plain Old Data, I don't think that can be done with data structures defined with an instance of a class. – Roger Nelson Sep 17 '08 at 05:06
  • 10
    Struct - For POD (plain old data) and all member accessibility is public. Class - When you need better encapsulation and need member functions to work with the class's state. – Navaneeth K N Jul 28 '09 at 03:51
  • 7
    This is true only by convention. There is no difference, apart from default encapsulation. – Dave Hillier Jul 28 '09 at 04:46
  • 1
    @Dave - that convention is the most important reason to do this. If it is followed consistently, that single difference immediately provides a lot of information to readers. – Tom Oct 27 '09 at 02:32
  • 12
    I believe that there is no serious reason for using structs in C++. To me structs are another redundant "feature" of C++ that exists only for compatibility with C, like typedefs. These would not exist if C++ was not initially treated as an extension to C, and was designed from scratch, such as Java. In general, I find that many of the weirdest things about C++ have to do with C compatibility. – Kostas Jun 26 '09 at 11:31
  • You're spot-on. I personally believe that the other language designers borrowed this idiom from C++ developers. – Tom Oct 27 '09 at 02:36
  • memset a struct, vs memset a class. – EvilTeach Dec 17 '12 at 18:38
  • 2
    @EvilTeach: `memset a struct, vs memset a class.` there is no difference in C++. It depends on whether what you `memset` is a POD-type or not. – Sebastian Mach Apr 07 '14 at 11:16
  • What happens if it is not a POD? – EvilTeach Apr 07 '14 at 12:20
  • 4
    @JasonBunting note that for C# it is more than a "semantic" difference. Structs are treated like values and passed by value as opposed to classes. – Matthias Apr 28 '17 at 17:38
  • 1
    @Matthias - We are coming up on 9 years since I wrote that, and it seems some intermediate comments were deleted. That said, I did say "Structs are really useful for creating value types, classes are not," and it's precisely for the reason you mention. – Jason Bunting May 24 '17 at 20:51
  • This [question](https://softwareengineering.stackexchange.com/questions/262463/should-we-add-constructors-to-structs) is somewhat relevant, what if we want to add only constructors to structs to initialize data. – zar Nov 14 '17 at 21:23
  • @Kostas writes "[structs] would not exist if C++ was not initially treated as an extension to C, and was designed from scratch, such as Java." Maybe, maybe not. I designed an OOP system (within a Lisp dialect), not compatible with any existing OOP system, in which classes are called "structs". They exhibit inheritance and polymorphism and all that. I could easily have chosen to use the "class" terminology. So it is not a given that a from-scratch, clean slate design will use "class" instead of "struct". – Kaz Feb 15 '18 at 02:28
  • IMO - this is one of the (many) areas of borkage from "C with classes" to C++. Classes with pure static dispatch, and class with pure virtual dispatch are very different beasts. With C++ we got an in-obvious mixture that has tripped up many programmers over the years. Not brilliant. – Preston L. Bannister Aug 24 '20 at 03:28
  • I'm closing this question as a duplicate. The target is asking essentially the identical question, but as a c++-faq question it appears to be maintained more than this question. There's also nothing useful on this question that isn't covered in the other. Please ping me if you disagree with the direction of the duplicate targets. If you feel the questions should be merged, you can raise a custom moderator flag asking for that (please explain clearly in the flag why they should be merged, and point to duplicate answers as well). – cigien Dec 11 '22 at 06:42

27 Answers27

1086

The differences between a class and a struct in C++ are:

  • struct members and base classes/structs are public by default.
  • class members and base classes/structs are private by default.

Both classes and structs can have a mixture of public, protected and private members, can use inheritance, and can have member functions.

I would recommend you:

  • use struct for plain-old-data structures without any class-like features;
  • use class when you make use of features such as private or protected members, non-default constructors and operators, etc.
Zitrax
  • 19,036
  • 20
  • 88
  • 110
Commodore Jaeger
  • 32,280
  • 4
  • 54
  • 44
  • 134
    A struct with no modifiers or methods is called a POD struct, which exists as a backwards compatible interface with C libraries as it is (supposedly) guaranteed to be laid out as though it were a C struct. Apart from this one exception though, the only difference is as stated. – workmad3 Sep 18 '08 at 14:22
  • 41
    @workmad3: The name is misleading, but 9/4 (C++03) says: "A POD-struct is an aggregate class that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator and no user-defined destructor." There is no restriction on using the "struct" class-key and no restriction on using "public" (see 8.5.1/1 for aggregate requirements). This is not a difference between "struct" and "class". –  Sep 22 '10 at 20:31
  • 6
    Your use of "aggregate" could be misunderstood, given the standard's definition. :) –  Sep 22 '10 at 20:32
  • 6
    According to Stroustrup's "Principles and Practice" book: "structs should primarily be used where the members can take any value" (i.e. where no meaningful class invariant can be defined) – antibus Dec 30 '14 at 13:57
  • The important thing about a POD struct is that it behaves identical to the same struct in a C compiler, so if you made weird assumptions in your C code like being able to memcpy consecutive members, those assumptions don't break when you use the same code in C++. A class will obviously never behave the same as in a C compiler (because in C, it doesn't compile). – gnasher729 Feb 11 '15 at 08:04
  • 8
    Of course you may use classes when interfacing with C. There is no difference between classes and structs. Structs are classes; only default access is flipped from private to public. – Sebastian Mach Mar 17 '16 at 12:58
  • 2
    The same applies for the default inheritance. For that reason, I would prefer structs: public inheritance (is-a) is far more common than private inheritance (is-implemented-in-terms-of). – Matthias Apr 28 '17 at 17:40
  • "I would recommend using structs as plain-old-data structures...". Why? Is there any advantage in using structs over classes (when you don't have to worry about C compatibility)? – deetz Oct 12 '17 at 06:25
  • 1
    Bjorne Stroustrup's "The C++ Programming Language" book, 4th edition, copyright 2013, page 48: `[Struct] Having the data specified separately from the operations on it has advantages, such as the ability to use the data in arbitrary ways. [Class] However, a tighter connection between the representation and the operations is needed for a user-defined type to have all the properties expected of a "real type."` – mellow-yellow Apr 04 '18 at 14:33
  • what is the technical need to even have private members? everything works fine if they're all public right? is it just simply for the programmer to organize and understand what variables aren't going to be used elsewhere? what really is the code physically changing when something is private vs public? – Puddle Jun 10 '18 at 05:24
  • @Puddle It has an impact on layout (https://stackoverflow.com/q/15763091/560648) but otherwise no. It's a programmer's tool that doesn't affect the meaning of the program. Producing a well-designed class that does not allow external factors to modify `private` variables makes it easier to maintain invariants in your class and thus prove the correctness of your program. tl;dr: otherwise too easy to create bugs – Lightness Races in Orbit Oct 26 '18 at 10:20
  • 3
    @mellow-yellow It's unfortunate (but not terribly unusual) that someone of Bjarne's would-be authority continues to peddle such poor choices in terminology. Per the standard of his own language, he's misrepresenting the distinction! Assuming that was a verbatim quote, anyway. – Lightness Races in Orbit Nov 01 '18 at 20:17
  • 1
    What is class-like features – Voyager Mar 11 '19 at 06:47
  • @Voyager everything that serves for OOP like member functions and inheritance. – AlexGeorg Nov 29 '19 at 08:19
  • I know, that you can declare a struct packed, But I dont know If you can pack a c++ class... Means alignment is also a difference. – Nikolai Ehrhardt Dec 29 '20 at 18:37
  • You might want to mention that the primary difference between struct and class is one of convention. Structs exist in C, to gather data into meaningful chunks. So C++ convention is to use struct for the same purpose. It may have functions, but it's purpose is to gather data. Classes were introduced to allow functions to be defined along with the data they operate on (objects). Most programmers keep to this convention. Structs are used where the data is the main point. Classes are used where the functional API is the main point. It's really all about intention. – Tiger4Hire Aug 18 '21 at 11:22
  • which one is faster? –  Nov 01 '21 at 22:56
  • The bit about "class-like features" is quite circular reasoning, as stated. – StayOnTarget Oct 18 '22 at 19:12
288

As everyone else notes there are really only two actual language differences:

  • struct defaults to public access and class defaults to private access.
  • When inheriting, struct defaults to public inheritance and class defaults to private inheritance. (Ironically, as with so many things in C++, the default is backwards: public inheritance is by far the more common choice, but people rarely declare structs just to save on typing the "public" keyword.

But the real difference in practice is between a class/struct that declares a constructor/destructor and one that doesn't. There are certain guarantees to a "plain-old-data" POD type, that no longer apply once you take over the class's construction. To keep this distinction clear, many people deliberately only use structs for POD types, and, if they are going to add any methods at all, use classes. The difference between the two fragments below is otherwise meaningless:

class X
{
  public:

  // ...
};

struct X
{
  // ...
};

(Incidentally, here's a thread with some good explanations about what "POD type" actually means: What are POD types in C++?)

Community
  • 1
  • 1
quark
  • 15,590
  • 3
  • 42
  • 30
  • Nice example regarding the inheritance differences: [here](http://blog.stevedoria.net/20050913/differences-between-cpp-classes-and-structs). – Liran Orevi Sep 13 '10 at 13:33
  • 13
    Whether you use `struct` or `class` has no bearing on whether your object is POD or whether you should define a copy constructor / destructor. Member functions also have no bearing on something being POD. As I re-read what you wrote, I see you aren't suggesting otherwise, but the current wording is confusing – David Stone Nov 23 '14 at 00:50
  • 1
    @DavidStone Basically, POD structs are supposed to be guaranteed to be backwards-compatible with C code, and thus are basically supposed to just be designed as C-style structs. – Justin Time - Reinstate Monica Feb 21 '16 at 00:16
  • @juanchopanza how so? Are there any other differences you're aware of? – rdelfin Jan 29 '21 at 11:17
  • 1
    @rdelfin I think I must have misread the paragraph, because the question is about differences between `struct` and `class` and when it comes to object layout there aren't any. The POD thing also change a bit since C++11. The bullet points are correct though. it is just about the defaults when you use either keyword to define a class. – juanchopanza Jan 29 '21 at 21:11
270

There are lots of misconceptions in the existing answers.

Both class and struct declare a class.

Yes, you may have to rearrange your access modifying keywords inside the class definition, depending on which keyword you used to declare the class.

But, beyond syntax, the only reason to choose one over the other is convention/style/preference.

Some people like to stick with the struct keyword for classes without member functions, because the resulting definition "looks like" a simple structure from C.

Similarly, some people like to use the class keyword for classes with member functions and private data, because it says "class" on it and therefore looks like examples from their favourite book on object-oriented programming.

The reality is that this completely up to you and your team, and it'll make literally no difference whatsoever to your program.

The following two classes are absolutely equivalent in every way except their name:

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

You can even switch keywords when redeclaring:

class Foo;
struct Bar;

(although this breaks Visual Studio builds due to non-conformance, so that compiler will emit a warning when you do this.)

and the following expressions both evaluate to true:

std::is_class<Foo>::value
std::is_class<Bar>::value

Do note, though, that you can't switch the keywords when redefining; this is only because (per the one-definition rule) duplicate class definitions across translation units must "consist of the same sequence of tokens". This means you can't even exchange const int member; with int const member;, and has nothing to do with the semantics of class or struct.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 27
    This was very informative, and honestly my favorite answer. Everyone else is treating them as separate entities, when underneath the hood, they are the same. I wonder if a struct definition in the Arduino environment is considered a cpp class, seeing as it's compiled using g++. – Benjamin Apr 24 '17 at 05:07
  • 5
    @Ben Of course it is. The Arduino compiler compiles C++; that's the end of it. – underscore_d May 22 '17 at 16:52
  • 11
    So if I'm understanding this right: As long as your visibility modifiers are explicit, not omitted, it doesn't matter. You could write a huge C++ application using nothing but structs; or you could go through and change every case of struct to class. As long as you're not using default visibility, the applications would be precisely the same. – Ryan Lundy Sep 29 '17 at 16:36
  • I'm not convinced that one translation unit of a C++ program can have the complete declaration `class foo { public: ... };` and another can have `struct foo { ... };` which would have to hold true according to the "absolutely equivalent" claim. It comes to reason that the incomplete declarations `struct foo;` and `class foo;` are interchangeable. These do not specify the class body, and so they speak nothing to the access layout. – Kaz Feb 15 '18 at 02:36
  • @Kaz: You're right - if the definitions were for literally the same type, they must be lexically identical for the behaviour to be well-defined. The _struct-key_ and _class-key_ are otherwise logically exchangeable though (where the semantics are not affected), and `Foo` and `Bar` are still equivalent/identical types. I did make sure to say "when _redeclaring_" and give an example. Come to think of it, I'll clarify this in the answer to make sure I'm not misleading people into UB – Lightness Races in Orbit Feb 15 '18 at 12:31
  • Your two answers use each other as a source. Why? – VLL Jan 28 '20 at 13:25
  • Don't underestimate the importance of convention. I once created a class that had no private or protected members, so I used `struct` to define it like I've seen the elite C++ dudes do it. The compiler was perfectly happy, but my coworkers were completely confused. They made me change it to `class` to match their conceptions. I was fine with that because in the end it made no difference. – Mark Ransom Jun 28 '22 at 04:09
  • This blew me away. Can someone tell me why for example in Swift and other languages structs seem to be preferred for creating models e.g. for REST APIs `struct ResponseModel: Codable` and classes are preferred for creating things like manager classes e.g. `class LocationManager: NSObject` etc. – Edison Oct 05 '22 at 02:43
56

The only time I use a struct instead of a class is when declaring a functor right before using it in a function call and want to minimize syntax for the sake of clarity. e.g.:

struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare()); 
Ferruccio
  • 98,941
  • 38
  • 226
  • 299
  • 40
    Now that it is several years later and C++11 is supported by all the major compilers, [Lambdas make this even more concise](http://stackoverflow.com/a/7627218/439793). –  Aug 14 '14 at 01:07
42

From the C++ FAQ Lite:

The members and base classes of a struct are public by default, while in class, they default to private. Note: you should make your base classes explicitly public, private, or protected, rather than relying on the defaults.

struct and class are otherwise functionally equivalent.

OK, enough of that squeaky clean techno talk. Emotionally, most developers make a strong distinction between a class and a struct. A struct simply feels like an open pile of bits with very little in the way of encapsulation or functionality. A class feels like a living and responsible member of society with intelligent services, a strong encapsulation barrier, and a well defined interface. Since that's the connotation most people already have, you should probably use the struct keyword if you have a class that has very few methods and has public data (such things do exist in well designed systems!), but otherwise you should probably use the class keyword.

Community
  • 1
  • 1
Tal Pressman
  • 7,199
  • 2
  • 30
  • 33
  • 3
    I don't understand why they are stating that struct and class are functionally the same, but saying to prefer the one over the other in certain cases without any reasoning.. – deetz Oct 12 '17 at 06:33
  • 6
    The reason is convention. The compiler doesn't care which one you use, but another developer looking at your code will have an easier time understanding what you meant. – Tal Pressman Oct 13 '17 at 07:43
  • 5
    @deetz: The entire third paragraph is reasoning. – Lightness Races in Orbit Feb 26 '18 at 02:13
  • Wow, coming from 'old school' I had no idea that a struct could have methods and even inheritance. I've always used struct for when using just data only with no methods and it's usually when dealing with API code that needs the struct. Can structs support multiple inheritance also? – Paul McCarthy Dec 17 '19 at 16:07
28

You can use "struct" in C++ if you are writing a library whose internals are C++ but the API can be called by either C or C++ code. You simply make a single header that contains structs and global API functions that you expose to both C and C++ code as this:

// C access Header to a C++ library
#ifdef __cpp
extern "C" {
#endif

// Put your C struct's here
struct foo
{
    ...
};
// NOTE: the typedef is used because C does not automatically generate
// a typedef with the same name as a struct like C++.
typedef struct foo foo;

// Put your C API functions here
void bar(foo *fun);

#ifdef __cpp
}
#endif

Then you can write a function bar() in a C++ file using C++ code and make it callable from C and the two worlds can share data through the declared struct's. There are other caveats of course when mixing C and C++ but this is a simplified example.

Adisak
  • 6,708
  • 38
  • 46
  • 4
    Best fitting answer. C-compatibility is really the most important reason. all other stuff like default access is esoteric. – Valentin H May 31 '15 at 22:32
27

One place where a struct has been helpful for me is when I have a system that's receiving fixed format messages (over say, a serial port) from another system. You can cast the stream of bytes into a struct that defines your fields, and then easily access the fields.

typedef struct
{
    int messageId;
    int messageCounter;
    int messageData;
} tMessageType;

void processMessage(unsigned char *rawMessage)
{
    tMessageType *messageFields = (tMessageType *)rawMessage;
    printf("MessageId is %d\n", messageFields->messageId);
}

Obviously, this is the same thing you would do in C, but I find that the overhead of having to decode the message into a class is usually not worth it.

start2learn
  • 23
  • 2
  • 7
mbyrne215
  • 2,304
  • 4
  • 21
  • 16
  • The same can be achieved in C. – Eugene Bujak Jun 16 '09 at 08:48
  • 13
    Or you could just implement `operator >>` on a class instead of writing the `processMessage` function, which would make your C++ look more like proper C++ and less like C. – Nick Bastin Jun 20 '10 at 18:29
  • 4
    Besides the fact that it's not portable between different systems, this violates aliasing rules, so it's not guaranteed to work even within a single architecture. – underscore_d May 22 '17 at 16:58
  • 1
    @underscore_d This can work platform (but not compiler) independent, but you must used fixed bitfields, a `__packed__` struct and have an endian-aware ifdef implementaion (you need to flip the order on a machine where the endianess is opposite what the external data source is providing). It's not pretty, but I have used to pack/unpack registers for remote peripherals on embedded platforms in a portable way. – crasic Dec 11 '17 at 19:45
  • @crasic But that's not really "portable", is it? After going to all the effort to lock yourself into one implementation like that, do you really feel it was quicker than simply writing standard-compliant code to do the unpacking? Serious question. I've gone to some lengths to write such code myself, and it ultimately wasn't too hard and was very educational. – underscore_d Dec 12 '17 at 09:44
  • 1
    @underscore_d Quite portable for the lifetime of a project or codebase for an embedded system, and an ADC won't change its register set for 30 years. It does the job, its single cycle, and easily testable, and can be handed to kernel drivers, `void*` system calls, and passed between C and C++,I say win-win? – crasic Dec 12 '17 at 09:55
  • @underscore_d Doesn't aliasing rules only apply to non-char function arguments? – jacwah Jan 04 '18 at 14:22
  • 2
    @jacwah Huh, good point. Aliasing won't be a problem here because one of the pointers is a `char` type, which are exempt from aliasing. However, there is still a problem, albeit a different one: Casting a `char*` to a different type, if there was not really any object of the latter type already initialised at that address, is UB as it violates lifetime rules. Afaik, even if the destination type is trivially constructible, just having allocated memory is not sufficient for C++ to formally allow treating that memory as that type. – underscore_d Jan 04 '18 at 15:35
  • I'd like to point out that "typedef struct { ... } tMessageType" isn't really necessary in C++ (as opposed to C) and that "struct tMessageType { ... }" is more concise and generally preferred. See [here](https://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions) for details. – Some Guy Jul 16 '21 at 02:50
  • Well if one use that kind of tricks, I would recommand to isolate the transformation in functions so that if you need to later support different architecture or compiler, you only have to rewrite function that read or write the structure from/to raw data. – Phil1970 Aug 01 '22 at 13:15
20

As every one says, the only real difference is the default access. But I particularly use struct when I don't want any sort of encapsulation with a simple data class, even if I implement some helper methods. For instance, when I need something like this:

struct myvec {
    int x;
    int y;
    int z;

    int length() {return x+y+z;}
};
ogoid
  • 405
  • 4
  • 8
  • 4
    +1 for giving an example of a struct with some member functions which do not feel like you've "taken away the structness". – einpoklum Feb 05 '17 at 19:33
13

To answer my own question (shamelessly), As already mentioned, access privileges are the only difference between them in C++.

I tend to use a struct for data-storage only. I'll allow it to get a few helper functions if it makes working with the data easier. However as soon as the data requires flow control (i.e. getters/setters that maintain or protect an internal state) or starts acquring any major functionality (basically more object-like), it will get 'upgraded' to a class to better communicate intent.

Alan Hinchcliffe
  • 12,862
  • 3
  • 18
  • 11
12

For C++, there really isn't much of a difference between structs and classes. The main functional difference is that members of a struct are public by default, while they are private by default in classes. Otherwise, as far as the language is concerned, they are equivalent.

That said, I tend to use structs in C++ like I do in C#, similar to what Brian has said. Structs are simple data containers, while classes are used for objects that need to act on the data in addition to just holding on to it.

Andy
  • 30,088
  • 6
  • 78
  • 89
12

Structs (PODs, more generally) are handy when you're providing a C-compatible interface with a C++ implementation, since they're portable across language borders and linker formats.

If that's not a concern to you, then I suppose the use of the "struct" instead of "class" is a good communicator of intent (as @ZeroSignal said above). Structs also have more predictable copying semantics, so they're useful for data you intend to write to external media or send across the wire.

Structs are also handy for various metaprogramming tasks, like traits templates that just expose a bunch of dependent typedefs:

template <typename T> struct type_traits {
  typedef T type;
  typedef T::iterator_type iterator_type;
  ...
};

...But that's really just taking advantage of struct's default protection level being public...

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
argv0
  • 775
  • 6
  • 12
  • 1
    That is not the correct usage of POD. A struct (or class) can be POD struct if (and only if) it contains ONLY POD members. – Martin York Mar 05 '09 at 08:07
  • 4
    "predictable copying semantics": The symantics are the same as for class (and have the same problems (shallow copy)). – Martin York Mar 05 '09 at 08:09
  • 2
    This post would have you believe (hopefully by accident) that all structs are PODs. This is not at all true. I hope that people are not mislead by this. – Michael Dorst Jul 30 '14 at 15:41
9

As others have pointed out

  • both are equivalent apart from default visibility
  • there may be reasons to be forced to use the one or the other for whatever reason

There's a clear recommendation about when to use which from Stroustrup/Sutter:

Use class if the class has an invariant; use struct if the data members can vary independently

However, keep in mind that it is not wise to forward declare sth. as a class (class X;) and define it as struct (struct X { ... }). It may work on some linkers (e.g., g++) and may fail on others (e.g., MSVC), so you will find yourself in developer hell.

pasbi
  • 2,037
  • 1
  • 20
  • 32
  • 1
    Can you describe these linker problems? – Lightness Races in Orbit Feb 23 '19 at 18:30
  • @LightnessRacesinOrbit I can't, unfortunately. I'm not even able to craft an example. The trivial `class Foo; struct Foo { void bar() {} }; int main() { Foo().bar(); }` not only compiles and runs with MSVC 2017, it even produces a clear warning that `Foo` was declared as `struct` but defined as `class`. But I also remember clearly that it cost our team half a day to find that stupid bug. I'm not sure what MSVC version we've used back then. – pasbi Feb 23 '19 at 21:39
  • The linker shouldn't even _know_ about whether you used `class` or `struct` on a forward declaration, and the two are freely interchangeable per the standard (though it is known that VS warns; I always assumed that was just to avoid apparent programmer mistakes). Something doesn't smell right here. Are you sure it wasn't an ODR violation bug? – Lightness Races in Orbit Feb 23 '19 at 21:42
  • 2
    Hmm, [seems VS is non-compliant in this regard](https://stackoverflow.com/q/33483623/560648) (go figure) – Lightness Races in Orbit Feb 23 '19 at 21:44
  • I don't remember exactly. The problem did not occur in an application directly, but in a library which was used in a gtest. I just know that the linker produced incomprehensible errors (LNK???). Once I replaced the `struct`-forwards to `class`-forwards, the problems went away. As of today, I find it strange, too. I'd be glad if you could shed some light on it. – pasbi Feb 23 '19 at 22:14
  • Click on the link I gave – Lightness Races in Orbit Feb 24 '19 at 02:51
8

An advantage of struct over class is that it save one line of code, if adhering to "first public members, then private". In this light, I find the keyword class useless.

Here is another reason for using only struct and never class. Some code style guidelines for C++ suggest using small letters for function macros, the rationale being that when the macro is converted to an inline function, the name shouldn't need to be changed. Same here. You have your nice C-style struct and one day, you find out you need to add a constructor, or some convenience method. Do you change it to a class? Everywhere?

Distinguishing between structs and classes is just too much hassle getting into the way of doing what we should be doing - programming. Like so many of C++'s problems it arises out of the strong desire for backwards compatibility.

Vorac
  • 8,726
  • 11
  • 58
  • 101
  • Why would you need to change it to a `class`? Did you think that a class defined with the `struct` keyword can't have member functions or a constructor? – Lightness Races in Orbit Feb 26 '18 at 02:16
  • @LightnessRacesinOrbit because of 1. consistency and 2. some static analysers complain about the violation of 1. – Vorac Feb 27 '18 at 15:27
  • That doesn't follow. What other "consistencies" do you adhere to? Every class with a member called `joe()` must be defined with `class` keyword? Every class with at least 4 `int` members must be defined with `struct` keyword? – Lightness Races in Orbit Feb 27 '18 at 17:11
  • @LightnessRacesinOrbit I am referring to the idiom "POD aggregates are defined with `struct`, aggregates with methods are defined with `class`". Too much hassle. – Vorac Feb 28 '19 at 07:37
8

Both struct and class are the same under the hood though with different defaults as to visibility, struct default is public and class default is private. You can change either one to be the other with the appropriate use of private and public. They both allow inheritance, methods, constructors, destructors, and all the rest of the goodies of an object oriented language.

However one huge difference between the two is that struct as a keyword is supported in C whereas class is not. This means that one can use a struct in an include file that can be #include into either C++ or C so long as the struct is a plain C style struct and everything else in the include file is compatible with C, i.e. no C++ specific keywords such as private, public, no methods, no inheritance, etc. etc. etc.

A C style struct can be used with other interfaces which support using C style struct to carry data back and forth over the interface.

A C style struct is a kind of template (not a C++ template but rather a pattern or stencil) that describes the layout of a memory area. Over the years interfaces usable from C and with C plug-ins (here's looking at you Java and Python and Visual Basic) have been created some of which work with C style struct.

Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
  • This answer contradicts itself: They are the "same under the hood" yet there is "one huge difference". Huh? If the C++ implementation treats the struct specially to preserve compatibility as described, then they are *not* necessarily the same "under the hood". The rest of the description is clear and compatible with other answers and comments, but if there is a difference, then just explain that directly without having to backtrack from the opening declaration. At least provide a proper context to the first sentence like "If either type is used completely within a C++ context, then..." – C Perkins Oct 05 '20 at 02:48
  • 1
    The "same under the hood", the hood being C++ internals; "huge difference" above the hood, outside of C++ proper. – Pablo H Sep 03 '21 at 14:20
  • Here's looking at the phrase I never anticipated hearing outside of Casablanca. – tejasvi88 Dec 11 '21 at 08:54
  • @tejasvi88 Two phrases, one from Casablanca and one from The King and I. Lol. – Richard Chambers Dec 11 '21 at 14:06
  • @CPerkins It is not a contradiction... This answer **clearly explain** that it is mostly the **same for C++** but **not for C**. – Phil1970 Aug 01 '22 at 13:32
5

They are pretty much the same thing. Thanks to the magic of C++, a struct can hold functions, use inheritance, created using "new" and so on just like a class

The only functional difference is that a class begins with private access rights, while a struct begins with public. This is the maintain backwards compatibility with C.

In practice, I've always used structs as data holders and classes as objects.

enigmatic
  • 295
  • 1
  • 5
4

Class.

Class members are private by default.

class test_one {
    int main_one();
};

Is equivalent to

class test_one {
  private:
    int main_one();
};

So if you try

int two = one.main_one();

We will get an error: main_one is private because its not accessible. We can solve it by initializing it by specifying its a public ie

class test_one {
  public:
    int main_one();
};

Struct.

A struct is a class where members are public by default.

struct test_one {
    int main_one;
};

Means main_one is private ie

class test_one {
  public:
    int main_one;
};

I use structs for data structures where the members can take any value, it's easier that way.

sehe
  • 374,641
  • 47
  • 450
  • 633
farhan
  • 458
  • 2
  • 8
  • 24
4

After years of programming in C++, my main language, I come to the dead conclusion that this is another one of C++ dumb feature.

There is no real difference between the two, and no reason why I should spend extra time deciding whether I should define my entity as a struct or a class.

To answer this question, feel free to always define your entity as a struct. Members will be public by default which is the norm. But even more importantly, inheritance will be public by default. Protected inheritance, and even worse, private inheritance, are the exceptions.

I have never had a case where private inheritance was the right thing to do. Yes I tried to invent problems to use private inheritance but it didn't work. And Java, the role model of Object Oriented programming defaults to public inheritance if you don't use the accessor keywords. And by the way, Java doesn't allow accessor keywords on inherited classes, they can only be publicly inherited. So you can see, the cpp team really fell down here.

Another frustrating thing about this, is that if you define as a class and declare as a struct you get compilation warning. As though this is something that impacted the performance or accuracy of your program. One answer also noted that MSVC may propogate a compiler error instead.

Those persons that use classes when it is raining and structs when it is shining are doing so based on what they have been taught. It's not something they discovered to be true. Java does not have a pair of names for classes, and only have the class keyword. If you want a data structure, simply make all your members public and don't add functions. This works in Java and I don't see any problem. What's the problem? You need 4 or 5 characters of BOM code to determine how to interpret the context of a class entity.

user13947194
  • 337
  • 5
  • 7
  • It is indeed unfortunate that the correct keyword to declare a class in C++ is `struct`. – Vorac May 27 '22 at 22:39
3

they're the same thing with different defaults (private by default for class, and public by default for struct), so in theory they're totally interchangeable.

so, if I just want to package some info to move around, I use a struct, even if i put a few methods there (but not many). If it's a mostly-opaque thing, where the main use would be via methods, and not directly to the data members, i use a full class.

Javier
  • 60,510
  • 8
  • 78
  • 126
3

Structs by default have public access and classes by default have private access.

Personally I use structs for Data Transfer Objects or as Value Objects. When used as such I declare all members as const to prevent modification by other code.

anio
  • 8,903
  • 7
  • 35
  • 53
3

Just to address this from a C++20 Standardese perspective (working from N4860)...

A class is a type. The keywords "class" and "struct" (and "union") are - in the C++ grammar - class-keys, and the only functional significance of the choice of class or struct is:

The class-key determines whether ... access is public or private by default (11.9).

Data member default accessibility

That the class keyword results in private-by-default members, and `struct keyword results in public-by-default members, is documented by the examples in 11.9.1:

class X { int a; // X::a is private by default: class used

...vs...

struct S { int a; // S::a is public by default: struct used

Base class default accessibility

1.9 also says:

In the absence of an access-specifier for a base class, public is assumed when the derived class is defined with the class-key struct and private is assumed when the class is defined with the class-key class.

Circumstances where consistent use of struct or class is required...

There's a requirement:

In a redeclaration, partial specialization, explicit specialization or explicit instantiation of a class template, the class-key shall agree in kind with the original class template declaration (9.2.8.3).

...in any elaborated-type-specifier, the enum keyword shall be used to refer to an enumeration (9.7.1), the union class-key shall be used to refer to a union (11.5), and either the class or struct class-key shall be used to refer to a non-union class (11.1).

The following example (of when consistency is not required) is provided:

struct S { } s; class S* p = &s; // OK

Still, some compilers may warn about this.


Interestingly, while the types you create with struct, class and union are all termed "classes", we have...

A standard-layout struct is a standard layout class defined with the class-key struct or the class-key class.

...so in Standardese, when there's talk of a standard-layout struct it's using "struct" to imply "not a union"s.

I'm curious if there are similar use of "struct" in other terminology, but it's too big a job to do an exhaustive search of the Standard. Comments about that welcome.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • I thought there was some difference regarding the "typedef name space", where, for compatibility with C, you can write `typedef struct A A` and use either `struct A` or plain `A` to declare/define variables, etc., but it seems that's not the case. It seems you can use both `struct` or `class` in that way. – Pablo H Sep 03 '21 at 14:27
1

Technically both are the same in C++ - for instance it's possible for a struct to have overloaded operators etc.

However :

I use structs when I wish to pass information of multiple types simultaneously I use classes when the I'm dealing with a "functional" object.

Hope it helps.

#include <string>
#include <map>
using namespace std;

struct student
{
    int age;
    string name;
    map<string, int> grades
};

class ClassRoom
{
    typedef map<string, student> student_map;
  public :
    student getStudentByName(string name) const 
    { student_map::const_iterator m_it = students.find(name); return m_it->second; }
  private :
    student_map students;
};

For instance, I'm returning a struct student in the get...() methods over here - enjoy.

Maciek
  • 19,435
  • 18
  • 63
  • 87
1

When would you choose to use struct and when to use class in C++?

I use struct when I define functors and POD. Otherwise I use class.

// '()' is public by default!
struct mycompare : public std::binary_function<int, int, bool>
{
    bool operator()(int first, int second)
    { return first < second; }
};

class mycompare : public std::binary_function<int, int, bool>
{
public:
    bool operator()(int first, int second)
    { return first < second; }
};
Khaled Alshaya
  • 94,250
  • 39
  • 176
  • 234
1

I use structs when I need to create POD type or functor.

ivan.ukr
  • 2,853
  • 1
  • 23
  • 41
1

All class members are private by default and all struct members are public by default. Class has default private bases and Struct has default public bases. Struct in case of C cannot have member functions where as in case of C++ we can have member functions being added to the struct. Other than these differences, I don't find anything surprising about them.

Helping Bean
  • 147
  • 7
0

I use struct only when I need to hold some data without any member functions associated to it (to operate on the member data) and to access the data variables directly.

Eg: Reading/Writing data from files and socket streams etc. Passing function arguments in a structure where the function arguments are too many and function syntax looks too lengthy.

Technically there is no big difference between class and struture except default accessibility. More over it depends on programming style how you use it.

harik
  • 563
  • 2
  • 5
  • 16
-7

I thought that Structs was intended as a Data Structure (like a multi-data type array of information) and classes was inteded for Code Packaging (like collections of subroutines & functions)..

:(

GaiusSensei
  • 1,860
  • 4
  • 25
  • 44
-10

I never use "struct" in C++.

I can't ever imagine a scenario where you would use a struct when you want private members, unless you're willfully trying to be confusing.

It seems that using structs is more of a syntactic indication of how the data will be used, but I'd rather just make a class and try to make that explicit in the name of the class, or through comments.

E.g.

class PublicInputData {
    //data members
 };
Baltimark
  • 9,052
  • 12
  • 37
  • 35
  • 1
    According to me, a "syntactic indication of how data will be used" is a perfectly good reason to use a struct, especially if the alternative is to use a comment or a name in the classname. – Viktor Sehr Jun 26 '09 at 11:41
  • 3
    Wouldn't declaring a `struct` already be pretty explicit that the members of the class will be, by default, public? – wrongusername Sep 15 '11 at 04:57