6

The other topic and responses there made me ask this question:

Why does C++ allow struct to behave just like class? At one hand, C++ made it compatible with C-struct by making it's members public by default (just like in C), while on the other hand, it made it look-like class by allowing it to be inherited from classes, and applying other object-oriented techniques (not so much like C-struct anymore). Why did it not make it just plain old C-struct with no OOP? Any special reason?

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 7
    Your recent questions on "Why C++ blah blah..." can all be answered by "Why not?". I like that C++ does it this way, and people who developed the standard liked it too, that's why they did it. – Yakov Galka Dec 13 '10 at 10:24
  • 1
    @ybungalobill : Nowadays I'm not only exploring C++ syntax/usage, but also the philosophy behind them. That's why you see "Why C++ blah blah..". :-) – Nawaz Dec 13 '10 at 10:26
  • 6
    then perhaps you should read "the design and evolution of c++" – jk. Dec 13 '10 at 12:18
  • 1
    @jk : it seems. I think I should start reading. Thanks for the advice.:-) – Nawaz Dec 13 '10 at 12:21

6 Answers6

7

It allows existing structs to be fitted in with C++ code in a more natural way. For instance, you can add member functions to a struct and inherit from a struct, which wouldn't be possible if structs and classes inhabited different universes.

Stroustrup's original intent was to avoid a fracturing of the community between the traditional C-style "struct" camp, and the OO "class" crowd. He also cited the benefits of having just one concept instead of two.

Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • "It allows existing structs to be fitted in with C++ code in a more natural way. For instance, you can add member functions to a struct [..] "... yes that's my question : why it allows us to add member functions? We've class for that, right? – Nawaz Dec 13 '10 at 10:29
  • @Nawaz it also allows adding member functions to unions. We can't use classes instead of unions, for the purpose they are used for. – Johannes Schaub - litb Dec 13 '10 at 10:32
  • @ Johannes Schaub: In 'union' case, it makes sense, since " We can't use classes instead of unions, for the purpose they are used for". Makes perfect sense. But how about struct? – Nawaz Dec 13 '10 at 10:37
  • It seems that the better solution to minimizing fracturing would have been to not create the `class` keyword at all. `struct` has the much better default, anyway. You can create a useful `struct` without mentioning any access specifiers or `friend` declarations, but you cannot do so with `class`. If you need anything more specific than everything public, you have to spell it out regardless of which construct you use. – David Stone Nov 23 '14 at 00:53
6

From a language point of view, structures and unions are just types of class. It makes the language specification simpler if there are fewer concepts (with a small letter 'c') and it also makes specifying the language less error prone as it is less easy to miss something 'obvious' out if every common property had to spelled out for each of structures, unions and non-structure, non-union classes.

C++ classes have a lot of potential functionality over C structures but as C structures can be viewed as a degenerate C++ class, it is simplest to allow them to be exactly this. There is no benefit to having a special structure concept as well as a class concept.

From ISO/IEC 14882:2003, 9 [class] / 4:

A structure is a class defined with the class-key struct; its members and base classes are public by default. A union is a class defined with the class-key union; its members are public by default and it holds only one data member at a time.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
2
  1. "public" default for struct fields is required for compatibility with C code which may access struct fields.
  2. "public" default for struct inheritance is required so that the child class could be used in place of base struct.
  3. It could be possible to make struct into a different data type than classes (ie disallow access type specifiers and methods in it), but that would be both inconvenient for programming and add a lot of unnecessary work for compiler developers.
Shelwien
  • 2,160
  • 15
  • 17
  • first two points are irrelevant I think here, as it doesn't attempt to answer my question. The 3rd point, the second half statement doesn't seem to be true. We've already used struct in C. So using plain c-struct is not at all inconvenient! – Nawaz Dec 13 '10 at 10:35
  • 1-2 are there because these are the reasons why a new keyword for class had to be added. And by "inconvenient" I mean incremental changes. ie according to you, when i'd like to protect one field of a structure copy-pasted from C project, I'd have to rename it to class and declare all other members public instead, and possibly go fix all the inheritance. – Shelwien Dec 13 '10 at 11:14
1

In C there were only structs to begin with. Object orientation began when libraries were designed when pointers to those structures were passed to a set of library functions that were dependent on that structure. One good example is the Win32 API. It isn't a C++ interface, it's a C interface; but it's still object oriented.

Classes are almost the same as structures memory-wise. The member functions are not stored as part of the class member data. It's simply a structure with extra function pointers on the end. So a class' function table is dereferenced in the same way that Windows API uses object orientation, but it encapsulates it so you don't see it.

Inheritance, polymorphism; who cares? People were fine with C, and still doing fine with C.

oldSkool
  • 1,212
  • 5
  • 14
  • 29
  • school rules : I liked this post as well. Good post. :-) +1 from me! – Nawaz Dec 13 '10 at 10:50
  • school: Please note that the extra function pointers (vtable) is only needed when virtual functions are involved. "Normal" member functions are resolved statically and do not require additional memory. – Fabio Fracassi Dec 13 '10 at 12:11
1

Allowing something you declare as struct to really be a class allows type-safety when creating a C interface.

You can forwardly declare your struct for your C interface:

struct Foo;

You can declare methods on it

void doStuffThatModifiesFoo( struct Foo * foo, ... );
struct Bar getStuffFromFoo( const struct Foo * foo );

You can also write create and destroy methods for it.

Underneath you implement Foo not as a C struct but as a class but your C clients do not need to know that. This is better than passing it around as a void * then casting (not safe if someone passes you a void* to a completely different type and you cast it).

CashCow
  • 30,981
  • 5
  • 61
  • 92
  • 1
    Strictly speaking, this isn't a class-vs-struct thing. The same trick is possible in pure C. – Marcelo Cantos Dec 13 '10 at 10:26
  • But it's still helpful when you are implementing something in C++, but need to expose the class with its member functions as a struct with global function. – Mephane Dec 13 '10 at 10:52
0

The "compatibility with C" issue is only meant in one direction: Old, valid C-code should also compile as C++ code. The other way round is impossible as soon as any language feature that only C++ has is being used.

That means in C++, you always write classes, you can omit using the keyword struct at all ; though some, including me, think they come in handy to show that a class just a simple collection of named values, with no real encapsulation or possibly complex behaviour.

Mephane
  • 1,984
  • 11
  • 18
  • Many modern C++ styleguides prefer using struct because it defaults to public, so you get to read the public interface first. – Fabio Fracassi Dec 13 '10 at 12:16
  • @Fabio: Hmm, "many"? I don't think I've ever seen anyone style guides suggest this. I tend to do it when I can get away with it though, for the reason you stated, but I can't recall seeing it recommended anywhere else. Got an example? – jalf Dec 13 '10 at 14:54
  • @jalf: I don't know if they have written it down somewhere, but it is quite common in boost code. LLVM seems to use it only for some parts (templates?). – Fabio Fracassi Dec 15 '10 at 09:31
  • @Fabio there's nothing preventing your from starting with the public interface in a `class` definition. – Mephane Jan 03 '11 at 08:11