By Alan Hinchcliffe


2008-09-10 16:29:54 8 Comments

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

24 comments

@pasbi 2018-09-17 11:05:27

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.

@Lightness Races in Orbit 2019-02-23 18:30:08

Can you describe these linker problems?

@pasbi 2019-02-23 21:39:41

@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.

@Lightness Races in Orbit 2019-02-23 21:42:44

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 2019-02-23 21:44:03

@pasbi 2019-02-23 22:14:34

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.

@Lightness Races in Orbit 2019-02-24 02:51:09

Click on the link I gave

@Lightness Races in Orbit 2016-04-28 14:17:34

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.

@Benjamin 2017-04-24 05:07:45

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++.

@underscore_d 2017-05-22 16:52:38

@Ben Of course it is. The Arduino compiler compiles C++; that's the end of it.

@Ryan Lundy 2017-09-29 16:36:17

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.

@Kaz 2018-02-15 02:36:51

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.

@Lightness Races in Orbit 2018-02-15 12:31:08

@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 2018-02-15 12:32:39

@Ryan: that's right.

@Helping Bean 2018-10-15 16:32:02

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.

@Commodore Jaeger 2008-09-10 16:35:23

Differences between a class and a struct in C++ are that structs have default public members and bases and classes have default private members and bases. 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 using structs as plain-old-data structures without any class-like features, and using classes as aggregate data structures with private data and member functions.

@workmad3 2008-09-18 14:22:13

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.

@Roger Pate 2010-09-22 20:31:18

@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".

@Roger Pate 2010-09-22 20:32:55

Your use of "aggregate" could be misunderstood, given the standard's definition. :)

@antibus 2014-12-30 13:57:50

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)

@gnasher729 2015-02-11 08:04:08

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).

@Sebastian Mach 2016-03-17 12:58:06

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.

@Matthias 2017-04-28 17:40:44

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).

@deetz 2017-10-12 06:25:34

"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)?

@mellow-yellow 2018-04-04 14:33:24

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."

@Puddle 2018-06-10 05:24:03

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?

@Lightness Races in Orbit 2018-10-26 10:20:49

@Puddle It has an impact on layout (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 2018-11-01 20:17:10

@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.

@Voyager 2019-03-11 06:47:20

What is class-like features

@Vorac 2017-11-14 21:08:34

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 compatability.

@Lightness Races in Orbit 2018-02-26 02:16:54

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?

@Vorac 2018-02-27 15:27:54

@LightnessRacesinOrbit because of 1. consistency and 2. some static analysers complain about the violation of 1.

@Lightness Races in Orbit 2018-02-27 17:11:09

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?

@Vorac 2019-02-28 07:37:19

@LightnessRacesinOrbit I am referring to the idiom "POD aggregates are defined with struct, aggregates with methods are defined with class". Too much hassle.

@Frrank 2017-11-07 22:41:55

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.

@mbyrne215 2008-09-10 16:43:01

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.

@Eugene Bujak 2009-06-16 08:48:22

The same can be achieved in C.

@Nick Bastin 2010-06-20 18:29:26

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.

@underscore_d 2017-05-22 16:58:47

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.

@crasic 2017-12-11 19:45:18

@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.

@underscore_d 2017-12-12 09:44:36

@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.

@crasic 2017-12-12 09:55:34

@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?

@jacwah 2018-01-04 14:22:26

@underscore_d Doesn't aliasing rules only apply to non-char function arguments?

@underscore_d 2018-01-04 15:35:09

@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.

@ivan.ukr 2016-09-15 09:30:25

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

@argv0 2008-09-10 17:46:48

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...

@Martin York 2009-03-05 08:07:51

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 2009-03-05 08:09:25

"predictable copying semantics": The symantics are the same as for class (and have the same problems (shallow copy)).

@Michael Dorst 2014-07-30 15:41:13

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.

@quark 2009-07-28 04:02:20

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++?)

@Liran Orevi 2010-09-13 13:33:43

Nice example regarding the inheritance differences: here.

@David Stone 2014-11-23 00:50:21

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

@Justin Time 2016-02-21 00:16:02

@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.

@juanchopanza 2017-07-29 23:31:51

The "real difference" part of this answer is totally wrong.

@Tal Pressman 2009-07-28 04:07:46

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.

@deetz 2017-10-12 06:33:48

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..

@Tal Pressman 2017-10-13 07:43:15

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.

@Lightness Races in Orbit 2018-02-26 02:13:29

@deetz: The entire third paragraph is reasoning.

@Adisak 2009-10-27 01:50:38

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.

@Valentin Heinitz 2015-05-31 22:32:46

Best fitting answer. C-compatibility is really the most important reason. all other stuff like default access is esoteric.

@AraK 2009-07-28 20:40:22

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; }
};

@sehe 2017-11-12 00:23:20

This answer is showing signs of age :) std::binary_function<> is not just deprecated, c++17 even removes it.

@Lightness Races in Orbit 2018-02-26 02:15:54

Not a surprise really since it was written in the time of C++03, a language defined 15 years ago.

@ogoid 2009-07-28 16:13:06

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;}
};

@einpoklum 2017-02-05 19:33:27

+1 for giving an example of a struct with some member functions which do not feel like you've "taken away the structness".

@Maciek 2009-07-28 04:42:17

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.

@harik 2009-07-28 04:29:10

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.

@GaiusSensei 2009-07-28 04:07:59

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)..

:(

@anio 2009-07-28 03:51:02

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.

@Javier 2009-07-28 03:49:00

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.

@Ferruccio 2008-09-10 18:08:44

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()); 

@user439793 2014-08-14 01:07:28

Now that it is several years later and C++11 is supported by all the major compilers, Lambdas make this even more concise.

@Baltimark 2008-09-10 18:02:25

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
 };

@Viktor Sehr 2009-06-26 11:41:51

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.

@wrongusername 2011-09-15 04:57:39

Wouldn't declaring a struct already be pretty explicit that the members of the class will be, by default, public?

@Lightness Races in Orbit 2018-02-26 02:17:39

Code-sharing with C is a very good reason.

@Alan Hinchcliffe 2008-09-10 16:50:18

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.

@enigmatic 2008-09-10 16:36:17

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.

@Andy 2008-09-10 16:36:00

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.

Related Questions

Sponsored Content

23 Answered Questions

1 Answered Questions

[SOLVED] The Definitive C++ Book Guide and List

  • 2008-12-23 05:23:56
  • grepsedawk
  • 2185889 View
  • 4248 Score
  • 1 Answer
  • Tags:   c++ c++-faq

36 Answered Questions

16 Answered Questions

[SOLVED] What are metaclasses in Python?

8 Answered Questions

17 Answered Questions

[SOLVED] Are static class variables possible in Python?

21 Answered Questions

[SOLVED] What is the "-->" operator in C++?

27 Answered Questions

[SOLVED] How do you set, clear, and toggle a single bit?

28 Answered Questions

[SOLVED] When to use struct?

  • 2009-02-06 17:37:55
  • Alex Baranosky
  • 252713 View
  • 1323 Score
  • 28 Answer
  • Tags:   c# struct

11 Answered Questions

[SOLVED] What does the explicit keyword mean?

Sponsored Content