In C++, why struct is in fact class? - c++

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?

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.

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.

"public" default for struct fields is required for compatibility with C
code which may access struct fields.
"public" default for struct inheritance is required so that the child class
could be used in place of base struct.
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.

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.

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

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.

Related

Why C language isn't Object Oriented language even though it has (Structures) struct keyword which is same as Class keyword of C++?

In a recent interview I was asked a question that what is the difference between Class and Structures which led me to think that if the difference is just about access specifier and we can use struct keyword in C then why isn't C object oriented.
Can anyone solve my doubt? This doubt might be naive but curiosity has it's own way.
A problem with this question is that in order to give an answer, we first need to define "what is an object oriented language".
An OO language like C++ has many features mapped into the language but that doesn't mean that any language need to have all thoses feature to be considered object-oriented.
What is required?
Encapsulation?
Inheritance?
Polymorfism?
... and so on ...
To me one of the most important features is encapsulation. With encapsulation you tie together the data that describes the object and the operations you can do with the object.
For instance a car object. It will have data members to describe its color, type of gear, number of gears, number of wheels, current speed and so on. Then it will have (member) functions to operate the car. You can accelerate, break, turn left and so on. The operations and the data are encapsulated, i.e. when an operation is carried out on an object by calling a function, all data describing the object is available to the function.
This encapsulation is a key feature of object oriented programming.
Encapsulation can't be handle by C.
We can make a struct with data members. We can even add (member) functions (aka function pointers) for the operations. So using proper initialization of a C struct object, we can write OO-style code like
mycar.getSpeed();
but...
C has no automatic relation between the members. We can't call a member function and automatically have access to the data of that object. C has no concept of encapsulation.
In C when calling a member function that needs access to data members of the same object, we need to pass (the address of) the object itself in order to get access to the data. Like:
mycar.getSpeed(&mycar);
\------------/ \^^^^^/
oo style but explicit passing pointer to
call the object violates the encapsulation principle
In a object oriented language this is often called the this pointer, and it is available implicit - you don't need to pass it. But in C you will have to pass it explicit. So the benefit of using function pointer members to get OO-style operations is (typically) small - we can just as well do:
getSpeed(&mycar);
The lack of encapsulation is one reason that C isn't object oriented.
In C++, the main difference between a struct and a class is that members of a struct are public by default, while members of a class are private by default.
A struct in C is different because it cannot contain member functions nor does it support inheritance. It is only a means of aggregating variables of differing types. While it can contain function pointers, they are not inherently tied to a given object like member functions in C++.
While the C language defines an "object" as "region of data storage in the execution environment, the contents of which can represent values" (C11 3.15), a struct is not an object in terms of being object-oriented, i.e. an encapsulated set of data and the functions that operate on them.
In C++ class and struct are keywords that can be used to declare a class. The fact that C is missing the keyword class does not make it less object oriented. What does it make "less object oriented" is that C structures cannot have member methods, in particular they do not have constructors nor destructors.
However, there is no clear cut between object oriented and non-object oriented languages. Object orientation is a paradigm, and languages can natively support it more or less. For example, is Python not object oriented because it has no "real" encapsulation? Certainly not. Moreover, consider that C++ started as C with classes. Many object oriented features that are built-in in C++ can be emulated in C.
why isn't C object oriented
Short answer - C wasn't designed with object-oriented programming in mind. C++ was.
The chief difference between a struct in C and a class or struct in C++ is that you can't (easily) associate code with a struct in C. You can't execute a method on a struct instance in C, such as
list.sort();
or
sequence.average();
Instead, you have to pass those struct instances as arguments to functions, like
sort( &list ); // have to pass a pointer since we're going to modify list
average( sequence );
C just doesn't provide the kinds of tools that make object-oriented programming easy - no encapsulation, no inheritance, no polymorphism (well, there's _Generic, but it's not quite the same).
You can do object-oriented programming in C, but it is a lot of work for arguably little benefit.

C++ Structs - Pointless? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What are the differences between struct and class in C++
I'm just trying to figure out if using 'C structs' in C++ are essentially useless or not. Do you gain anything by using them (opposed to simply creating another class)?
In C the point of structs is obvious, simply contiguous allocations of grouped data and a nice way to access said data, in C++ I feel the role becomes a little more vague.
Seeing as that you can have functions which are members of structs, instance variables, and visibility labels, the only real difference that I see between structs and classes in C++ is that struct members default to public while class members default to private. The way I see them, they can actually both be implemented with the same exact underlying system.
So am I missing something here as to the purpose of structs in C++? Or have they kind of lost their purpose, as I feel they have in C++?
In my opinion, Structures doesn't give you anything that can't be implemented by a class.
But, Structures are kept in C++ in order to have backward compatibility with c
Classes and structures in C++ are almost the same, the only things that separates them is that the default visibility of a class is private while in a struct it's public.
The reason to keep having structures in C++ was probably to keep the language compatible with C, so it would be easier to port C code to C++, or for programmers to make that transition.
As for the usage of structures contra classes, I personally use them just like would in C, to group related variables together in a single "object".
Undoubtedly the reason they are there is for compatibility with C. But you are right, although there are small differences between class and struct in C++ there is nothing you can do with structs that you cannot do with classes (and vice versa).
Personally I use structs only when the same declaration would be legal in C, to emphasize the C-like nature of whatever it is I'm doing.
They are implemented "with the same exact underlying system". In fact, you can actually declare a type using class keyword and then define it using struct keyword. Basically, they are exactly the same aside from the conceptual difference you already mentioned: default access rights.
I don't see though why would one call them "useless". The usage of the keyword became a matter of personal preference and/or coding standard. Like "use struct fro POD types", or "use struct for types with no incapsulation/access control".
With the same degree of success one can declare the built-in -> operator "useless" because of its equivalence to *+. combination.
You can have the same behavior as in C, nobody forces you to use the additional "class" features. So if you understand their purpose in C, it should be understandable in C++ as well (the "C-like" portion at least).
As Joachim Pileborg already pointed out, classes and structures are almost the same thing in C++.
I would, however, recommend to use struct for "dumb" data holders with public members and class for properly encapsulated classes as a style convention.

Difference between a struct and a class [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between struct and class in C++
I've done my homework and had diverse answers on Google.
Some say structs do not have inheritance, some say structs do not have access specifiers, while others say they have both.
Could someone clarify then, the differences between a struct and a class in C and C++, and also the difference between a struct in C & C++.
In C++, the only difference between a struct and a class is that struct members are public by default, and class members are private by default.
However, as a matter of style, it's best to use the struct keyword for something that could reasonably be a struct in C (more or less POD types), and the class keyword if it uses C++-specific features such as inheritance and member functions.
C does not have classes.
C structs cannot use C++-specific features.
EDIT:
The C++ FAQ Lite, question 7.9, has this to say:
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.
And quoting Stroustrup's "The C++ Programming Language", 4th edition, section 16.2.4:
These two definitions of S are interchangeable, though it is
usually wise to stick to one style. Which style you use depends on
circumstances and taste. I tend to use struct for classes that I
think of as "just simple data structures." If I think of a class as "a
proper type with an invariant," I use class. Constructors and
access functions can be quite useful even for *struct*s, but as a
shorthand rather than guarantors of invariants.
In C, classes do not exist. In C++, structs have a default access specifier of public, while classes default to private.
There are several differences between structs in C and C++; in C++ they can inherit from other classes or structs, they can contain member functions, and their names don't need to be referred to with an elaborated type specifier.

Unions as Base Class

The standard defines that Unions cannot be used as Base class, but is there any specific reasoning for this? As far as I understand Unions can have constructors, destructors, also member variables, and methods to operate on those varibales. In short a Union can encapsulate a datatype and state which might be accessed through member functions. Thus it in most common terms qualifies for being a class and if it can act as a class then why is it restricted from acting as a base class?
Edit: Though the answers try to explain the reasoning I still do not understand how Union as a Derived class is worst than when Union as just a class. So in hope of getting more concrete answer and reasoning I will push this one for a bounty. No offence to the already posted answers, Thanks for those!
Tony Park gave an answer which is pretty close to the truth. The C++ committee basically didn't think it was worth the effort to make unions a strong part of C++, similarly to the treatment of arrays as legacy stuff we had to inherit from C but didn't really want.
Unions have problems: if we allow non-POD types in unions, how do they get constructed? It can certainly be done, but not necessarily safely, and any consideration would require committee resources. And the final result would be less than satisfactory, because what is really required in a sane language is discriminated unions, and bare C unions could never be elevated to discriminated unions in way compatible with C (that I can imagine, anyhow).
To elaborate on the technical issues: since you can wrap a POD-component only union in a struct without losing anything, there's no advantage allowing unions as bases. With POD-only union components, there's no problem with explicit constructors simply assigning one of the components, nor with using a bitblit (memcpy) for compiler generated copy constructor (or assignment).
Such unions, however, aren't useful enough to bother with except to retain them so existing C code can be considered valid C++. These POD-only unions are broken in C++ because they fail to retain a vital invariant they possess in C: any data type can be used as a component type.
To make unions useful, we must allow constructable types as members. This is significant because it is not acceptable to merely assign a component in a constructor body, either of the union itself, or any enclosing struct: you cannot, for example, assign a string to an uninitialised string component.
It follows one must invent some rules for initialising union component with mem-initialisers, for example:
union X { string a; string b; X(string q) : a(q) {} };
But now the question is: what is the rule? Normally the rule is you must initialise every member and base of a class, if you do not do so explicitly, the default constructor is used for the remainder, and if one type which is not explicitly initialised does not have a default constructor, it's an error [Exception: copy constructors, the default is the member copy constructor].
Clearly this rule can't work for unions: the rule has to be instead: if the union has at least one non-POD member, you must explicitly initialise exactly one member in a constructor. In this case, no default constructor, copy constructor, assignment operator, or destructor will be generated and if any of these members are actually used, they must be explicitly supplied.
So now the question becomes: how would you write, say, a copy constructor? It is, of course quite possible to do and get right if you design your union the way, say, X-Windows event unions are designed: with the discriminant tag in each component, but you will have to use placement operator new to do it, and you will have to break the rule I wrote above which appeared at first glance to be correct!
What about default constructor? If you don't have one of those, you can't declare an uninitialised variable.
There are other cases where you can determine the component externally and use placement new to manage a union externally, but that isn't a copy constructor. The fact is, if you have N components you'd need N constructors, and C++ has a broken idea that constructors use the class name, which leaves you rather short of names and forces you to use phantom types to allow overloading to choose the right constructor .. and you can't do that for the copy constructor since its signature is fixed.
Ok, so are there alternatives? Probably, yes, but they're not so easy to dream up, and harder to convince over 100 people that it's worthwhile to think about in a three day meeting crammed with other issues.
It is a pity the committee did not implement the rule above: unions are mandatory for aligning arbitrary data and external management of the components is not really that hard to do manually, and trivial and completely safe when the code is generated by a suitable algorithm, in other words, the rule is mandatory if you want to use C++ as a compiler target language and still generate readable, portable code. Such unions with constructable members have many uses but the most important one is to represent the stack frame of a function containing nested blocks: each block has local data in a struct, and each struct is a union component, there is no need for any constructors or such, the compiler will just use placement new. The union provides alignment and size, and cast free component access.
[And there is no other conforming way to get the right alignment!]
Therefore the answer to your question is: you're asking the wrong question. There's no advantage to POD-only unions being bases, and they certainly can't be derived classes because then they wouldn't be PODs. To make them useful, some time is required to understand why one should follow the principle used everywhere else in C++: missing bits aren't an error unless you try to use them.
Union is a type that can be used as any one of its members depending on which member has been set - only that member can be later read.
When you derive from a type the derived type inherits the base type - the derived type can be used wherever the base type could be. If you could derive from a union the derived class could be used (not implicitly, but explicitly through naming the member) wherever any of the union members could be used, but among those members only one member could be legally accessed. The problem is the data on which member has been set is not stored in the union.
To avoid this subtle yet dangerous contradiction that in fact subverts a type system deriving from a union is not allowed.
Bjarne Stroustrup said 'there seems little reason for it' in The Annotated C++ Reference Manual.
The title asks why unions can't be a base class, but the question appears to be about unions as a derived class. So, which is it?
There's no technical reason why unions can't be a base class; it's just not allowed. A reasonable interpretation would be to think of the union as a struct whose members happen to potentially overlap in memory, and consider the derived class as a class that inherits from this (rather odd) struct. If you need that functionality, you can usually persuade most compilers to accept an anonymous union as a member of a struct. Here's an example, that's suitable for use as a base class. (And there's an anonymous struct in the union for good measure.)
struct V3 {
union {
struct {
float x,y,z;
};
float f[3];
};
};
The rationale for unions as a derived class is probably simpler: the result wouldn't be a union. Unions would have to be the union of all their members, and all of their bases. That's fair enough, and might open up some interesting template possibilities, but you'd have a number of limitations (all bases and members would have to be POD -- and would you be able to inherit twice, because a derived type is inherently non-POD?), this type of inheritance would be different from the other type the language sports (OK, not that this has stopped C++ before) and it's sort of redundant anyway -- the existing union functionality would do just as well.
Stroustrup says this in the D&E book:
As with void *, programmers should know that unions ... are inherently dangerous, should be avoided wherever possible, and should be handled with special care when actually needed.
(The elision doesn't change the meaning.)
So I imagine the decision is arbitrary, and he just saw no reason to change the union functionality (it works fine as-is with the C subset of C++), and so didn't design any integration with the new C++ features. And when the wind changed, it got stuck that way.
I think you got the answer yourself in your comments on EJP's answer.
I think unions are only included in C++ at all in order to be backwards compatible with C. I guess unions seemed like a good idea in 1970, on systems with tiny memory spaces. By the time C++ came along I imagine unions were already looking less useful.
Given that unions are pretty dangerous anyway, and not terribly useful, the vast new opportunities for creating bugs that inheriting from unions would create probably just didn't seem like a good idea :-)
Here's my guess for C++ 03.
As per $9.5/1, In C++ 03, Unions can not have virtual functions. The whole point of a meaningful derivation is to be able to override behaviors in the derived class. If a union cannot have virtual functions, that means that there is no point in deriving from a union.
Hence the rule.
You can inherit the data layout of a union using the anonymous union feature from C++11.
#include <cstddef>
template <size_t N,typename T>
struct VecData {
union {
struct {
float x;
float y;
float z;
};
float a[N];
};
};
template <size_t N, typename T>
class Vec : public VecData<N,T> {
//methods..
};
In general its almost always better not work with unions directly but enclose them within a struct or class. Then you can base your inheritance off the struct outer layer and use unions within if you need to.

Is it always evil to have a struct with methods?

I've just been browsing and spotted the following...
When should you use a class vs a struct in C++?
The consensus there is that, by convention, you should only use struct for POD, no methods, etc.
I've always felt that some types were naturally structs rather than classes, yet could still have a few helper functions as members. The struct should still be POD by most of the usual rules - in particular it must be safe to copy using memcpy. It must have all member data public. But it still makes sense to me to have helper functions as members. I wouldn't even necessarily object to a private method, though I don't recall ever doing this myself. And although it breaks the normal POD rules, I wouldn't object to a struct having constructors, provided they were just initialise-a-few-fields constructors (overriding assignment or destructors would definitely be against the rules).
To me a struct is intuitively a collection of fields - a data structure node or whatever - whereas a class is an abstraction. The logical place to put the helper functions for your collection-of-fields may well be within the struct.
I even think I once read some advice along these lines, though I don't remember where.
Is this against accepted best practice?
EDIT - POD (Plain Old Data) is misrepresented by this question. In particular, a struct can be non-POD purely because a member is non-POD - e.g. an aggregate with a member of type std::string. That aggregate must not be copied with memcpy. In case of confusion, see here.
For what it's worth, all the standard STL functors are defined as structs, and their sole purpose is to have member functions; STL functors aren't supposed to have state.
EDIT: Personally, I use struct whenever a class has all public members. It matters little, so long as one is consistent.
As far as the language is concerned, it doesn't matter, except for default private vs. public access. The choice is subjective.
I'd personally say use struct for PODs, but remember that "POD" doesn't mean "no member functions". It means no virtual functions, constructors, destructor, or operator=.
Edit: I also use structs for simple public-access aggregates of data, even if their members aren't PODs.
I tend to use struct a lot.
For the "traditional" OOP classes (the ones that represent a specific "thing"), I tend to use class simply because it's a common convention.
But most of my classes aren't really OOP objects. They tend to be functors, and traits classes and all sorts of other more abstract code concepts, things I use to express myself, rather than modelling specific "things". And those I usually make struct. It saves me having to type the initial public:, and so it makes the class definition shorter and easier to get an overview of.
I also lean towards making larger, more complex classes class. Except this rarely affects anything, because I lean even more towards refactoring large, complex classes... And then I'm left with small simple ones, which might be made struct's.
But in either case, I'd never consider it "evil". "Evil" is when you do something that actively obfuscates your code, or when you make something far more complex than necessary.
But every C++ programmer knows that struct and class mean virtually the same thing. You're not going to be confused for long because you see a struct Animal {...}; You know that it's a class designed to model an animal. So no, it's not "evil" no matter which way you do it.
When I have control over the style guides, everything is defined as a struct. Historically, I wanted all my objects to be one or the other, since I was taught it was undefined behavior to forward declared a struct as a class, and vice versa (I'm not sure if this was ever actually true, its just what I was told). And really, struct has the more reasonable default state.
I still do the same because I've never been convinced of the value of using it as a form of documentation. If you need to convey that an object only has public members, or doesn't have any member functions, or whatever arbitrary line you chose to draw between the two, you have actual documentation available for that. Since you never actually use the struct or class keyword when using the type, you would need to go hunting for the definition anyhow if you want the information. And with everybody having their own opinion on what struct actually means, its usefulness as self-documentation is reduced. So I shoot for consistency: everything as one or the other. In this case, struct.
Its not a popular way of doing things, to say the least. Fortunately for everybody involved, I very rarely have control over the coding standards.
I use a struct whenever I need an aggregate of public data members (as opposed to class, which I use for types that come with a certain level of abstractions and have their data private).
Whether or not such a data aggregate has member functions doesn't matter to me. In fact, I rarely ever write a struct without also providing at least one constructor for it.
You said, "To me a struct is intuitively a collection of fields - a data structure node or whatever". What you are describing is Plain Old Data. The C++ standard does have an opinion of what POD means with respect to C++ language features. I suggest that, where possible, you adopt the meaning of POD used in C++0x.
I need to find a reference for this, but I thought that, as far as type definitions are concerned, the keywords "struct" and "class" are to be synonyms in C++0x. The only difference being that class defaults to private members, while a struct defaults to public. This means that you'll never see complier error messages like "Type X first seen using struct, now seen using class." once we're all using C++0x.
I think that it is wrong to have strict rules on when to use class and when to use struct. If consistency is important to you, the go ahead and make a coding standard that has what ever sort of rules you like. Just make sure everyone knows that your coding standard relates to how you want you code to look - it doesn't relate to the underlying language features at all.
Maybe to give an example where I break all your rules, you say "To me a struct is intuitively a collection of fields - a data structure node or whatever - whereas a class is an abstraction." When I want to write a class that implements some abstraction, I define the interface as a struct with pure virtual methods (egad!) - this is exposed in a header, as too is a factory method to construct my concrete class. The concrete class is not exposed i a public header at all. Since the concrete class is a secret, it can be implemented however I like and it makes no difference to external code.
I'd suggest that if you think that the keywords struct and class have any relation to the concept of POD, then you're not understanding C++ yet.