C++ STruct vs Class

R

Robert Fendt

C struct is different from C++ struct

To be precise: a struct in C++ is a class that 'emulates' a struct in C, nothing more, nothing less. Structs can have constructors, virtual functions, you can inherit from them, etc.; not that you *should*, but you *can* anyway.

The rationale is, as long as it's a POD type (i.e., no virtual functions or other funny business) a struct (or a class) in C++ is storage compatible to a C struct. That is, you can declare something that is (1) storage compatible and (2) syntactically identical between C++ and C. That's what the purpose of struct is in C++. "Under the hood" there is not much difference to a class apart from the default encapsulation settings ('public' vs. 'private'), and you can destroy the syntax equivalence easily by using C++ specifics in the struct.

Regards,
Robert
 
H

Hamiral

Noah said:
> The C++ language makes no disctinction
between class and struct and so we should not either.
But a struct as all its members public by default, IIRC.

Ham
 
A

Anand Hariharan

Can any one demostrate the difference b/w C++ struc and classes??

Apart from the usual answer of what is private and public by default,
as language keywords, only 'class' may be used as a template
parameter.

- Anand
 
T

tonydee

To be precise: a struct in C++ is a class that 'emulates' a struct in C, nothing more, nothing less. Structs can have constructors, virtual functions, you can inherit from them, etc.; not that you *should*, but you *can* anyway.

I wouldn't say that was precise at all, and I'd say that's why you
felt the need to quote 'emulates'. "nothing more" followed by lots of
"more": constructors, virtual functions, inheritance... :). And an
unexplained (and incorrect) implication that struct's shouldn't use
these features. In particular, structs should often have constructors
as it makes them much easier to create.
The rationale is, as long as it's a POD type (i.e., no virtual functions or other funny business) a struct (or a class) in C++ is storage compatible to a C struct. That is, you can declare something that is (1) storage compatible and (2) syntactically identical between C++ and C. That's what the purpose of struct is in C++.

That's like saying the purpose of an array of ints is to be compatible
with C arrays of ints. Not so - the purpose is to store multiple
numbers. C++ is a near-superset of C and retains compatibly where
useful, layout and equivalent usage are kept the same as in C because
the benefits outweigh any negatives, but that doesn't mean extensions
aren't available or that the places where the "C" style usage is
optimal aren't narrowed by other C++ features (like those used to
build std::vector<>).

Returning to class and struct: they group related data, functions that
operate on them, supporting types and static data etc.. Having the
"class" keyword, pretty much redundant given "struct", allows
programmers to imbue the choice of keyword with a record of their
intent, so when they or a colleague looks at the code later it's clear
whether the programmer intended to have OO-style encapsulation vs a
pretty open interface with direct client access to member data. This
is just good self-documenting coding, and not enforced by the
language, though the implication is supported by the default access
and inheritance of private vs public. So, even in code that has no
interaction or relationship to any C code, programmers typically do
and should use a mix of structs and classes. See
http://www.artima.com/intv/goldilocks2.html.

Cheers,
Tony
 
P

Philip Potter

While the first part of that FAQ is technically correct, IMHO the second
half (the opinion bit) is wrong. The C++ language makes no disctinction
between class and struct and so we should not either.

That's like saying the C++ language makes no distinction between i=i+1;
and i++; [1] so we should not prefer one over the other. But clearly
i++; gives an impression of "next object" or "next index", while i=i+1;
gives an impression of arithmetical rather than structural code.[2]

The fact is that if you use a struct to create a datatype with only
private data members and a public interface defined only in terms of
member functions, you'll cause someone reading your code to get confused
as they ask themselves "Why didn't they use a class? Was there a reason
for this choice?"

When the language provides multiple ways of doing something, prefer the
more readable construct[3]; noting that readability is a function not
just of the construct itself but also of the expectations of the people
you expect to read it later. If the people who read your code expect a
class to be an encapsulated thing and a struct to be a bundle of
publicly-accessible bits of data, then you will increase readability by
satisfying these expectations.

Phil

[1] where i is nonvolatile integer or pointer type.
[2] and even arithmetical code should prefer i+=1;
[3] let's assume all other things, such as efficiency, are equal here.
 
Ö

Öö Tiib

While the first part of that FAQ is technically correct, IMHO the second
half (the opinion bit) is wrong.  The C++ language makes no disctinction
between class and struct and so we should not either.

That's like saying the C++ language makes no distinction between i=i+1;
and i++; [1] so we should not prefer one over the other. But clearly
i++; gives an impression of "next object" or "next index", while i=i+1;
gives an impression of arithmetical rather than structural code.[2]

Strange. Both sides agree that differences are only those of how human
reads the code (so it is matter of style policy), yet seem to disagree
with each other.

As for style policies ... i have seen several differentiations of
class and struct during years. These are like style policies about
indentation that rarely overlap completely. So the difference is what
you agree inside team, nothing more, nothing less.
 
J

James Kanze

While the first part of that FAQ is technically correct, IMHO
the second half (the opinion bit) is wrong. The C++ language
makes no disctinction between class and struct and so we
should not either.

People do, however, and one should write code to be written and
understood.

The real problem (which the FAQ doesn't mention) is that
different people expect different things when they see struct
instead of class. In general, within a project, it's probably a
good idea to establish some sort of conventions---something you
thing is relevant to communicate---and adhere to them. But not
to get caught up in the idea that it's something absolute,
because the conventions might be different the next place you
work. (On projects which are partly in C, it is a frequent
convention that anything declared as a struct can be used in C.
On other projects, I've seen a number of different conventions.)
 
J

James Kanze

Noah Roberts wrote:
But a struct as all its members public by default, IIRC.

If you define the class using the class specifier struct or
union, you start public. If you define the class using the
class specifier class, you start private. But you can always
use an access specifier whenever you like. (I think---I'm not
too sure about union.)
 
N

Noah Roberts

While the first part of that FAQ is technically correct, IMHO the second
half (the opinion bit) is wrong. The C++ language makes no disctinction
between class and struct and so we should not either.

That's like saying the C++ language makes no distinction between i=i+1;
and i++; [1] so we should not prefer one over the other.

If you say so. I would have to strongly disagree though since the
language very much DOES make a distinction. It's actually completely
different sets of operators that only result in similar actions in a few
cases.
But clearly
i++; gives an impression of "next object" or "next index", while i=i+1;
gives an impression of arithmetical rather than structural code.[2]

That's because it is only with arithmetical objects that the two
statements are equivelent. In other cases it's as vastly different as
calling function_a() vs. calling function_b() followed by a
reassignment. In fact, as you are almost certainly aware, many objects
will not respond to the latter even while responding to the former.
The fact is that if you use a struct to create a datatype with only
private data members and a public interface defined only in terms of
member functions, you'll cause someone reading your code to get confused
as they ask themselves "Why didn't they use a class? Was there a reason
for this choice?"

I used to ask that question. Then I learned better. I had also,
unfortunately, been taught that classes where made with "class" and PODS
with "struct". Then when I started learning more modern C++ methods I
had to unlearn that bad habbit.
When the language provides multiple ways of doing something, prefer the
more readable construct[3]; noting that readability is a function not
just of the construct itself but also of the expectations of the people
you expect to read it later. If the people who read your code expect a
class to be an encapsulated thing and a struct to be a bundle of
publicly-accessible bits of data, then you will increase readability by
satisfying these expectations.

The reason *some* code readers expect that there's a difference between
struct and class is because they are erroneously taught that there is.
For example, the OP and the FAQ to which I was responding. If people
stopped saying there's a difference even though there is not, then
people would stop expecting there to be one.

You're going to have trouble reading the boost source code and many
modern instructional books, for instance, if you keep expecting
"struct" to hold some special meaning that it simply does not have.

Kanze brings up a decent point that it could be used in some teams to
mean various things. Sure, OK. I wouldn't agree that it's a good
method of doing so though. Preferably something important enough to
require documentation in the code is documented in such a manner that
you don't have to go looking for that documentation. Naming something
somedata_POD for instance would, IMHO, be better for documenting POD
status that must be kept. There's almost certainly at least as many
people who expect "struct" to be nearly synonymous with "class" as there
are otherwise that you'd want to be more verbose about anything you're
wishing to document.

Since "struct" has defaults that make more sense with almost everything
we do, my team has actually settled on using struct for all
classes/pods/whatever. The only time "class" is used is for template
template parameters. I think you'll find that this is a very common
approach these days.
 
J

James Kanze

[...]
That's like saying the C++ language makes no distinction
between i=i+1; and i++; [1] so we should not prefer one over
the other.
If you say so. I would have to strongly disagree though since
the language very much DOES make a distinction. It's actually
completely different sets of operators that only result in
similar actions in a few cases.

The most important distinction is that in i=i+1, i is evaluated
two times. Replace i by a more complicated expression, with
side effects, and the meaning is definitely different.

And that's even without the issue of user defined overloads
(which I suppose was what you were refering to).

[...]
When the language provides multiple ways of doing something,
prefer the more readable construct[3]; noting that
readability is a function not just of the construct itself
but also of the expectations of the people you expect to
read it later. If the people who read your code expect a
class to be an encapsulated thing and a struct to be a
bundle of publicly-accessible bits of data, then you will
increase readability by satisfying these expectations.
The reason *some* code readers expect that there's a
difference between struct and class is because they are
erroneously taught that there is. For example, the OP and the
FAQ to which I was responding. If people stopped saying
there's a difference even though there is not, then people
would stop expecting there to be one.

There is a difference (other than the starting access): a struct
can potentially be shared with C code, if you use the keyword
class, it can't. (Of course, you need to meet other criteria as
well to share it with C.)
You're going to have trouble reading the boost source code and
many modern instructional books, for instance, if you keep
expecting "struct" to hold some special meaning that it simply
does not have.
Kanze brings up a decent point that it could be used in some
teams to mean various things. Sure, OK. I wouldn't agree
that it's a good method of doing so though. Preferably
something important enough to require documentation in the
code is documented in such a manner that you don't have to go
looking for that documentation. Naming something somedata_POD
for instance would, IMHO, be better for documenting POD status
that must be kept. There's almost certainly at least as many
people who expect "struct" to be nearly synonymous with
"class" as there are otherwise that you'd want to be more
verbose about anything you're wishing to document.
Since "struct" has defaults that make more sense with almost
everything we do, my team has actually settled on using struct
for all classes/pods/whatever. The only time "class" is used
is for template template parameters. I think you'll find that
this is a very common approach these days.

That's also a valid choice. I think that there are only two
cases where the choice isn't really fairly arbitrary:

-- You have existing code. IMHO, the difference in the various
choices isn't enough to justify changing from what was done
previously. If struct previously meant X, and class Y, I'd
just keep on doing it that way, for consistency's sake, and
because it's not worth going back and changing the existing
body of code.

-- You are managing a mixed C/C++ project. In which case, one
of the rules has to be to use struct with anything shared
with C++. And I'd probably favor making that the real
distinction here: struct means that the object can be shared
with C (even if it isn't currently).

In my experience, the choice has almost always been dominated by
the first rule. Whatever the reasons behind it initially.

In my own code, I'll admit that I'm not consistent. At one
point, I did decide on the rule: struct if it had public data,
class if not; but what about classes which have no data? More
and more, I'm using struct there as well, although my original
rules said class. As you say, more or less, it's just an
arbitrary keyword, and shouldn't really have more semantics than
those defined by the language, so why not choose the easiest
form to use?
 
N

Noah Roberts

In my own code, I'll admit that I'm not consistent. At one
point, I did decide on the rule: struct if it had public data,
class if not; but what about classes which have no data? More
and more, I'm using struct there as well, although my original
rules said class. As you say, more or less, it's just an
arbitrary keyword, and shouldn't really have more semantics than
those defined by the language, so why not choose the easiest
form to use?

The purpose in picking one keyword to use is so that you don't have to
look it up to do a forward declaration. Some compilers, such as MSVC++,
bitch about using struct when it was previously declared as class and
visa-versa. I don't believe they are supposed to, but they do. I
suppose you could shut off the warning.

I found though that I was prone to forgetting to make base classes
public when using "class", since it was the easier way fairly rarely,
and so just decided to no longer use that keyword at all.
 
T

tonydee

The purpose in picking one keyword to use is so that you don't have to
look it up to do a forward declaration.  Some compilers, such as MSVC++,
bitch about using struct when it was previously declared as class and
visa-versa.  I don't believe they are supposed to, but they do.  I
suppose you could shut off the warning.  

Excellent point - I've never encountered that issue, but then I
include headers (forward declaration headers if useful) and never
forward declare stuff in client code. Still, the common "rule of
thumb" re public data might not work so well here, as it's existence
may not be known to the client-code programmer. Further, if the
library code potentially needs modification in order to maintain the
struct-vs-class selection convention, then the client code will need
updating too else the convention will be misleading - either outcome
highly undesirable.
I found though that I was prone to forgetting to make base classes
public when using "class", since it was the easier way fairly rarely,
and so just decided to no longer use that keyword at all.

In terms or minimal coupling, it's got to be better to find you need
to expose something when you first start trying to use it, rather than
allowing an indefinite period where client code grows dependent on a
base class made public by accident....

Cheers,
Tony
 
N

Noah Roberts

In terms or minimal coupling, it's got to be better to find you need
to expose something when you first start trying to use it, rather than
allowing an indefinite period where client code grows dependent on a
base class made public by accident....

I've rarely found non-public inheritance useful. It's very rare that I
inherit from a class when I am not implementing an IS-A relation. There
are cases of course, but I've written many programs that never used non-
public inheritance.

A very good point though. I don't think it will change the way I'm
doing things since it's already rather set, at least in my current
project, but it's a good point.
 
J

James Kanze

The purpose in picking one keyword to use is so that you don't
have to look it up to do a forward declaration. Some
compilers, such as MSVC++, bitch about using struct when it
was previously declared as class and visa-versa.

That used to be true, but I don't think it's the case now. (And
you really shouldn't be using VC6. Although I'm pretty sure you
know that.)
I don't believe they are supposed to, but they do. I suppose
you could shut off the warning.
I found though that I was prone to forgetting to make base
classes public when using "class", since it was the easier way
fairly rarely, and so just decided to no longer use that
keyword at all.

I don't doubt that there are good justifications for this
policy. It's certainly as reasonable as any other. Getting
other people to buy into it may be more difficult, however, and
on a team, you want to follow the team's policies.
 
N

Noah Roberts

That used to be true, but I don't think it's the case now. (And
you really shouldn't be using VC6. Although I'm pretty sure you
know that.)

Who said anything about VC6?

Still haven't learned to have a reasonable conversation without getting
bitchy I see.
 
T

tonydee

Who said anything about VC6?

Still haven't learned to have a reasonable conversation without getting
bitchy I see.

Yikes - that was uncalled for. James apparently deduced VC6, thinking
it the only MSVC++ version in (too-)common use that warns about
mismatched declarations using struct vs class. From your response,
either he was wrong or you picked up the habit earlier and are no
longer using VC6 but retain the habit. No big deal, and nothing
"bitchy" anywhere....
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,149
Messages
2,570,843
Members
47,390
Latest member
RobertMart

Latest Threads

Top