6

Possible Duplicate:
What are the differences between struct and class in C++

I used to think that the only differences between C++ classes were the private-by-default class member access modifiers and the laid-out-like-C guarantee.

It turns out I was wrong, because this code doesn't compile:

class { int value; } var = { 42 };

whereas this does:

struct { int value; } var = { 42 };

I can't figure out why there's a difference, but there apparently is in Visual C++ 2008:

error C2552: 'var' : non-aggregates cannot be initialized with initializer list

So, yes, I will ask a many-times-over duplicate question (hopefully without duplicate answers!):

What are all the differences between structs and classes in C++?

Of course, feel free to close this if you find that I've missed something in the other questions -- I certainly might have. But I didn't see this being discussed in any of the answers, so I thought I'd ask.

Community
  • 1
  • 1
user541686
  • 205,094
  • 128
  • 528
  • 886
  • 2
    "aggregate" means that all members are public. – Kerrek SB Aug 25 '11 at 11:50
  • The first *is* the only difference between `struct` and `class` but they are crucial to your example. Because `value` is private in the first class the first class is not an aggregate so you can't use aggregate initialization for it. The "laid-out-like-C" guarantee is not a C++ guarantee. – CB Bailey Aug 25 '11 at 11:51
  • @Kerrek: "Aggregate" means "public"?! English isn't my first language... now I have a feeling may very well never be. :( – user541686 Aug 25 '11 at 11:56
  • 1
    @Mehrdad: Why "English"? I mean in the C++ standard, the term "aggregate" is thus defined. That has nothing to do with the meanings of "aggregate" in the English language, to my knowledge. – Kerrek SB Aug 25 '11 at 12:00
  • @Kerrek: Yes, it was indeed my bad to try and use common sense when interpreting the error message, rather than getting a copy of the standard and looking it up in there. Will try and keep this in mind for next time, thanks... – user541686 Aug 25 '11 at 12:01
  • So... do we close this now as a duplicate? :-) – Kerrek SB Aug 25 '11 at 12:12
  • @Kerrek: Indeed, please do! x__x If I happen to get a chance to see it at 4 votes then I'll cast the 5th one myself. ;) – user541686 Aug 25 '11 at 12:14

4 Answers4

15

You can use {} initializer for aggregates only1 and the first one is not an aggregate, as it has one private data member.

The Standard says in section §8.5.1/1,

An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).

1. Well, I meant, in C++03, you can use {} for aggregates ONLY, but in C++11, you can use {} even with non-aggregates (if the non-aggregate class is properly implemented to handle this).

Also see this for detail answer (on {} initializer):

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 4
    WOWWWW I feel so silly now. Adding `public:` fixes the issue. +1 thanks. *facepalm* – user541686 Aug 25 '11 at 11:53
  • I'm now kind of wondering -- *why* are we allowed to create a class like that in the first place? There's no legal way to access `x` (not even reflection), so shouldn't the compiler give an error or something? – user541686 Aug 25 '11 at 11:59
  • @Mehrdad: Actually you can. You can still create instances of such class. The compiler generated *public* constructor is there, and you can use [the instances more like handles!](http://www.ideone.com/c79Gd) – Nawaz Aug 25 '11 at 12:01
  • Use them as handles? Don't you at least need to be able to check them for equality (and differentiate between them)? – user541686 Aug 25 '11 at 12:03
  • @Mehrdad: Like this : http://www.ideone.com/c79Gd . Just check the addresses. Windows API uses such handles all the time! – Nawaz Aug 25 '11 at 12:04
  • Ohh I guesssssss that's *possible*, though it seems like a really roundabout way of making handles. Oh well, I guess that works. – user541686 Aug 25 '11 at 12:06
  • @Mehrdad: Also see this : [Handles Comparison: empty classes vs. undefined classes vs. void*](http://stackoverflow.com/questions/4525847/handles-comparison-empty-classes-vs-undefined-classes-vs-void) – Nawaz Aug 25 '11 at 12:06
  • Ah thanks for the link, that's pretty cool actually! – user541686 Aug 25 '11 at 12:08
4

That is not a difference between class and struct, but between aggregate and non-aggregates. You cannot use the initializer list with a non-aggregate type, but that is unrelated to the class or struct keyword:

class { public: int value; } var = {42};   // compiles
struct { private: int value; } var = {42}; // error
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
3

The difference is between public and private.

Try this instead:

class { public: int value; } var = { 42 };
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
1

It seems that members of a class are private as well as any inheritance is private where as a struct is all public.

Someone else will have to give you more specifics though, sorry.

Tony318
  • 552
  • 2
  • 9