Others have pointed out correctly that in C++ the keywords struct
and class
have the same meaning except for the difference in member visibility.
Whether you call aggregate types thus defined "structs" or "classes" or "weiruewzewiruz" is up to you. In the interest of communication it is generally advisable to follow established conventions, so I would advise against "weiruewzewiruz".
It is also recommended to use semantic differences as a guideline for word choices. The use of struct
is more common for simple aggregated data which does not have a lot of internal logic and invariants; a typical use would be struct point { float x; float y; };
. Such types are often called "structs" or "structures" in the literature. It would not be surprising if somebody using fprintf
in C++ referred to the first argument as a "pointer to a FILE struct". FILE is an example of what Scott Meyers' means in "More Effective C++", Item 34:
It is safe to assume that a structure definition that compiles in both
languages [C and C++ -p.a.s] is laid out the same way by both compilers.
Concerning the natural language, the word choice "structure" is not coincidental: Meyers is talking about a plain old data aggregate which has identical semantics in both languages, right down to the bit level.
Concerning programming language, it wouldn't matter if the C++ definition of the data aggregate in question used the keyword struct
or class
(with a public access specifier). struct
is perhaps the more natural choice, because the C++ semantics of the aggregate are the semantics of a C struct. Also, using struct
enables both C and C++ sources to easier share one type definition.
The C++ standard uses "struct" and "structure" both in natural and programming language, not only in cases of interoperability: 1.7/5: "A structure declared as", or 3.2/4 struct X; // declare X as a struct type
. Most interesting is 9/8, laying ground for interop-criteria:
8 A standard-layout struct is a standard-layout class
defined with the class-key struct or the class-key
class. [...]
How anybody reading this can claim that there are no structs in C++ is beyond me. This clearly is not an editing error because the terms "struct" and "class" are explicitly set in relation to each other.
More interesting than word choices and matters of taste, however, are manifest, testable differences. Under what circumstances is a C++ aggregate comparable to and compatible with a C struct
? Perhaps this question was underlying your question? The standard layout mentioned in the quote is the criteria. It is detailed in 9/7 and essentially prescribes that
- only one class in an inheritance hierarchy may have non-static data member definitions (probably because the standard does not want to specify the order of data elements defined at different levels in such a hierarchy);
- no virtual functions or virtual base classes are allowed (because of the additional instance data necessary for the run-time information);
- all members have the same "access control" (either public, protected or private; probably because an implementation is free to order by access control).
The standard then says
9 [ Note: Standard-layout classes are useful for communicating
with code written in other programming languages.
Their layout is specified in 9.2.—end note ]
Of course a struct definition which compiles in C fulfills these criteria, hence Scott Meyers' assertion. FILE
from stdio.h is a prominent, not-quite-trivial example. Note that the standard doesn't make guarantees because object layout is implementation dependent and may change just with a compiler option.
Whether a class has standard layout can be tested with the type trait std::is_standard_layout<T>
. The following program, which is inspired by an example on cppreference, checks the main cases laid out in the standard.
#include <cstdio>
#include <typeinfo>
#include <type_traits>
using namespace std;
struct funcOnlyT // fine
{
int f();
};
class podT { // "class" is ok
int m1;
int m2;
};
struct badAccessCtrlT { // bad: public/private
int m1;
private:
int m2;
};
struct polymorphicT { // bad: polymorphic
int m1;
int m2;
virtual void foo();
};
struct inheritOkT: podT // ok: inheritance, data only on one level
{
int f();
};
struct inheritPlusDataT: podT // bad: inheritance, data on 2 levels
{
int m3;
};
template<typename T1, typename T2>
struct templT // ok with std layout types T1, T2
{
T1 m1;
T2 m2;
};
// print type "name" and whether it's std layout
template<typename T>
void printIsStdLayout()
{
printf("%-20s: %s\n",
typeid(T).name(),
std::is_standard_layout<T>::value
? "is std layout"
: "is NOT std layout");
}
int main()
{
printIsStdLayout<funcOnlyT>();
printIsStdLayout<podT>();
printIsStdLayout<badAccessCtrlT>();
printIsStdLayout<polymorphicT>();
printIsStdLayout<inheritOkT>();
printIsStdLayout<inheritPlusDataT>();
printIsStdLayout<templT<int, float> >();
printIsStdLayout<FILE>();
}
Sample session:
$ g++ -std=c++11 -Wall -o isstdlayout isstdlayout.cpp && ./isstdlayout
9funcOnlyT : is std layout
4podT : is std layout
14badAccessCtrlT : is NOT std layout
12polymorphicT : is NOT std layout
10inheritOkT : is std layout
16inheritPlusDataT : is NOT std layout
6templTIifE : is std layout
9__sFILE64 : is std layout
(struct|class) MyClass : public BaseClass { private: ....
, there is no difference betweenstruct
andclass
. – Calashstruct
does not implyPOD struct
. – Calash