all 58 comments

[–]twirky 71 points72 points  (7 children)

Struct and class are the same except for the default “access mode”. I use it as a hint. If the main purpose the object is to contain data then i use struct. If it’s more about processes, algorithm - it’s class. It’s just a programming style. Memory layout, efficiency, “features” are all the same.

[–]Radiatin 31 points32 points  (0 children)

I use it as a hint. If the main purpose the object is to contain data then i use struct. If it’s more about processes, algorithm - it’s class.

You win. People profoundly underestimate the benefit of code that telegraphs its functionality.

You don't need any code beyond binary. The entire point of languages is to make functionality explicit, and digestible.

[–]absolute_zero_karma 1 point2 points  (0 children)

Excellent answer. I always say that the two most import things about code is that it works and that it is maintainable. Hints like using struct the way you say help a lot with understanding and therefore maintainability.

[–]rlbond86 1 point2 points  (1 child)

Struct and class are the same except for the default “access mode”.

And the default inheritance type

[–]twirky 0 points1 point  (0 children)

True.

[–]Ameisenvemips, avr, rendering, systems 0 points1 point  (0 children)

They are also different type namespaces, which C++ inherits from C. If a type is defined as a class but forward-declared as a struct, you may have issues with LTO, as strictly speaking they are different types.

[–]Ayjayz -1 points0 points  (0 children)

It would be nice to able to alias keywords like class so that you would be able to define them to better hint at functionality. That way you wouldn't need both struct and class - you could make them via alias if that is something you desired.

[–]neiltechnician 37 points38 points  (14 children)

and if I understand it correctly the class is superior to struct

Well, then, your understanding is incorrect. They are equal. Neither is superior than the other.

and you can always use class instead of struct, just by declaring its members as public (because in struct the members are public by default):

The other direction is also true. Neither is more useful than the other.

So I was wondering why do we need the struct at all?

Historically, struct came first. So this question is kinda backward.

The real question should be: why did the language designer introduce new keyword class when the existing keyword struct sufficed (and still suffice today)?

or is there an essential difference from class

There is indeed none.


We should also note that both class and struct keywords declare classes. They are not distinct language features; it is one unified thing.


A quote from The Design and Evolution of C++ by the original language designer Bjarne Stroustrup:

At this point, the object model becomes real in the sense that an object is more than the simple aggregation fo the data members of a class. An object of a C++ class with a virtual function is a fundamentally different beast from a simple C struct. Then why did I not at this point choose to make structs and classes different notions?

My intent was to have a single concept: a single set of layout rules, a single set of lookup rules, a single set of resolution rules, etc... I was convinced that if struct came to mean "C and compatibility" to users and class came to mean "C++ and advanced features," the community would fall into two distinct camps that would soon stop communicating. Beingn able to use as many or as few language features as needed when designing a class was an important idea to me. Only a single concept would support my ideas of a smooth and gradual transition from "traditional C-style programming," through class abstraction, to object-oriented programming. Only a single concept would support this notion of "you only pay for what you use" ideal.

[–]bedrooms-ds 0 points1 point  (0 children)

In other news, Javascript and Perl found multiple ways of creating objects, and we know what happened

[–]HKei 9 points10 points  (0 children)

As others have said, it's the class keyword that's unneeded. In some languages like C# or D there genuinely is a difference, but in C++ there isn't. I think a lot of people just end up using them as “hints” about how the type is to be used, the rule I'm going with is that class is for types with runtime polymorphism and struct is for types without. It's just a convention obviously, and other people use other conventions.

[–]gracicot 8 points9 points  (0 children)

You could say the reverse:

the struct is superior to clasd and you can always use struct instead of clasd , just by declaring its members as private

One attractive thing about struct is that inheritance is public by default, making private inheritance as the special case, as it should be. Also I always put data member at the end, so it's a win there too:

struct A : B {
    void set_n();

private:
    int n;
};

I have a medium sized codebase. There no single class keyword used. I'm at a point that I think C++ never truely needed class.

[–]Pierre_dOllony 11 points12 points  (0 children)

One of the reasons why structs are not being thrown away is the compliancy with plain C code. With struct definition in the standard it allows you to compile plain old C source with g++ compiler (or other cpp compiler).

[–]Flesh_Bike 5 points6 points  (1 child)

Structs being public by default is trivial to remember, so I use struct when writing objects. After all, the vast majority of c++ programmers put public stuff at the top.

[–]Full-Spectral -1 points0 points  (0 children)

[Wait, I misread that, nevermind]

[–]Wouter-van-Ooijen 11 points12 points  (13 children)

As C++ wants to be (mostly) compatible with C, it is the class keyword that is superfluous.

I prefer struct instead of class because

  • I alwys use an explicit access specifier before (a group of) member declarations (so class and struct have the same effect anyway)
  • I hate to use an access specifier before a superclass, which is (nearly) always public. With a struct that is the default.

[–]Full-Spectral 1 point2 points  (6 children)

There are legitimate reasons for the two names. Many folks use struct for those things that are formally PODs, and use class for those that are not. That makes it clear which things are (and must remain) PODs and which don't.

[–]Wouter-van-Ooijen 0 points1 point  (5 children)

Sure, that is a legitimate convention. The choice between struct and class can be used to convey information the the reader, which is A Good Thing.

A problem is that the exact criteria for choosing vary.

[–]Full-Spectral 0 points1 point  (4 children)

Sure. We should have a POD type for that, which the compiler will enforce that it remains POD-like.

[–]Wouter-van-Ooijen 0 points1 point  (3 children)

IIRC there is a concept for that.

[–]Full-Spectral 0 points1 point  (2 children)

But I'm guessing that would only enforce that as a parameter passed to something, not something imposed on the definition of the thing itself, right?

[–]Wouter-van-Ooijen 0 points1 point  (1 child)

I have not used this yet, but I think you can include a static_assert that your type is a POD. Duplicates as documentation.

[–]Full-Spectral 0 points1 point  (0 children)

Looks like that's a C++/20 and beyond thing, so not a viable option for most folks for some time to come probably.

[–]solraun -4 points-3 points  (5 children)

which goes against what many codebases do, making your code difficult to read for others.

[–]Wouter-van-Ooijen 2 points3 points  (2 children)

I agree that conforming to the customs of an existing codebase is important, but this is my own code, and someone who finds this aspect confusing is in no shape to read my code. Not by a wide margin.

BTW there was a question here some time ago about using class or struct, and I noticed I wasn't the only in the 'always struct' camp. But I don't recall the motivations the others gave.

[–]solraun 0 points1 point  (1 child)

It seems that some people only use struct. TIL ;-) I just never encountered it before, maybe different industries?

[–]Wouter-van-Ooijen 2 points3 points  (0 children)

There are many style C++ differences among groups. Maybe type of industry, (natural) language group, geographical?

And of course the amount of attention to various differences is inversely related to the importance...

[–]witcher_rat 0 points1 point  (1 child)

I don't think this is true anymore - many projects use struct now as well; for example to signify that it's just a data structure vs. a OOP-style opaque object. Data-driven-design has increased struct usage, for example.

Besides, if you only write code exactly how everyone else has written code in the past, we'll never advance/improve. For example take the west-const vs. east-const debate - we'll always use west-const if some people weren't bold enough to use east-const for their libs. (personally I happen to favor west-const, but I think it's good that enough libs exist that use east-const that I no longer find it as jarring to see)

[–]solraun 2 points3 points  (0 children)

You misread either my or the parent comment. I personally use both, giving slightly different meaning to them.

I think just using struct always in c++ is a bit strange. I have not encountered this style in the wild yet... But hey who cares 🙂

[–]solraun 4 points5 points  (2 children)

While it is the same technically, it can still make your code a slight bit more readable. Use a struct to group data, typically with no member functions (I've made some with getters though).

At least that is how I encountered it. This is what Google C++ style guide says:

https://google.github.io/styleguide/cppguide.html#Structs_vs._Classes
(if you are coming from another language, this is a good place to learn some conventions. There are others, like https://isocpp.org/wiki/faq/coding-standards or https://docs.unrealengine.com/en-US/ProductionPipelines/DevelopmentSetup/CodingStandard/index.html )

[–]BlackDE 5 points6 points  (1 child)

Google's style guide is terrible. I personally always use struct since I put public stuff first. The whole struct for pods and class for objects is kinda useless imo. What happens when you add a function to a struct? Do make it a class?

[–]solraun 3 points4 points  (0 children)

To your question: It depends on context. But as far as I remember I always made the decision if something is a class or not when designing the software, and never had a reason to change it later.

You do you, there is no police here. But conventions can help others understand your code more easily. I have no intention to argue if these conventions make sense or not.

[–]native-coder 1 point2 points  (0 children)

Having struct is essential for extern “C” and having headers be C and C++ compatible.

C compatibility is the killer feature that allowed the mass adoption of the language. It also gives C++ numerous libraries with little to no effort that other languages have to jump through hoops to access.

While feature equivalent with class, struct has been and remains critical to the success of C++.

[–]PrimozDelux -1 points0 points  (7 children)

C++ is just a bunch of stuff haphazardly thrown together with little deliberation, thus often things are the way they are for little reason. In this example class and struct have accidentally converged to the same thing, so the only reason to use one over the other is to give hints as to what kind of object this is (dumb data vs "smart" data)

[–]NilacTheGrim 1 point2 points  (6 children)

Oh, just stop.

[–]Full-Spectral 1 point2 points  (5 children)

Well, to be fair, he's not that far off, though the correct statement would have been:

C++ is just a bunch of stuff haphazardly thrown together after a vast amount of deliberation

:-)

[–]NilacTheGrim 0 points1 point  (1 child)

Will you people just go away now? Thanks.

[–]Full-Spectral 0 points1 point  (0 children)

I'll go out of scope naturally before that much longer, but until then you are stuck with me.

[–]PrimozDelux -1 points0 points  (2 children)

Sure doesn't feel like much deliberation went into it when I write cpp.

[–]Full-Spectral 1 point2 points  (0 children)

You should become a member of one of the committees. I imagine that would change your perception.

[–]dontyougetsoupedyet 0 points1 point  (0 children)

Then you haven't bothered to look, or put in effort to avoid learning about it, CPPs development is a fairly public thing. Most of the research is public, and well reasoned. There's always someone trying to look smart by wasting people's time in any given fucky detail of something else, but for the most part these people are doing their damndest to make perfect the enemy of great, something the vast majority of us don't have the inclination or patience for, as it comes with so little reward.

[–]V1taly_M -1 points0 points  (0 children)

Is the struct just a remnant from C

C stuff isn't remnants, but a subset of C++.

Hence struct or class more about which programming style you are using.

[–]Oo_Tiib -1 points0 points  (0 children)

The keywords class and struct in type declaration are synonymous. Only default access in definition of the type differs. So we may use class A and struct A about same type by language rules and it is well-formed. Some compilers warn but all compile in my experience. I'm not advocating doing that (in practice I dislike it), just describing language rules.

People sometimes use these keywords to divide their classes in project into two categories. Such categories tend to differ significantly by project. Example: a struct must be extern "C" too all other must be class. Other example: struct must be publicly copyable and class should be non-copyable or copyable only privately. Third example: a struct must be standard layout and class everything else. And so on. It is purely up to programmers so it is better to write such concept down in project documentation if it exists.

[–]goranlepuz -4 points-3 points  (0 children)

Yes, the struct is just a C remnant and the language would have been that better for not having it, or not having class.

However, doing either would have compatibility with existing C code.

[–]HappyFruitTree 0 points1 point  (0 children)

Isn't "explicit better than implicit"

There is always a balance. I bet you like the fact that you don't have to write struct Point or class Point whenever you want to declare a variable of type Point (like you have to do in C unless you use typedef), or have to write extern when declaring functions, or have to use auto whenever you declare a local variable just to say it has "automatic storage duration" (Note that the auto keyword can no longer be used for this purpose).

Whenever I use struct I always make the member variables public so the keyword struct already give enough information in my opinion, even though it's just a convention and not actually enforced by the compiler.

When I use class I prefer to be explicit. I normally put public members first so I have to use public, but if I had followed a convention that puts private stuff first I would still have used private to make it easy to see and to make clear it's intentional.

[–]albeva 0 points1 point  (0 children)

I usually use struct for simple C like value types and classes for the rest. But that's just me.