I found a mistake in a C++ forward declaration of a class, which was wrongly declared as struct Book
instead of class Book
. I think Book used to be a struct, got changed to a class but the forward declarations remained.
Book.h:
class Book { ... };
Library.h:
struct Book; class Library { std::vector<Book*> books; };
There were no compiler warnings and the resulting program seemed to work fine. It made me curious: in theory, can this ever cause a problem? It's just a pointer, yes, but for example, if the class had virtual methods, multiple inheritance, could the pointers be different?
I know the differences between class/struct regarding default public/private but I'm asking specifically about the forward declarations and possible consequences of swapping them.
UPDATE newer versions of Xcode now give this warning when there's a mismatch:
Struct 'Book' was previously declared as a class; this is valid, but may result in linker errors under the Microsoft C++ ABI
In C++, classes and structs can be forward-declared like this: class MyClass; struct MyStruct; In C++, classes can be forward-declared if you only need to use the pointer-to-that-class type (since all object pointers are the same size, and this is what the compiler cares about).
Forward Declaration refers to the beforehand declaration of the syntax or signature of an identifier, variable, function, class, etc. prior to its usage (done later in the program). Example: // Forward Declaration of the sum() void sum(int, int); // Usage of the sum void sum(int a, int b) { // Body }
The Google style guide recommends against using forward declarations, and for good reasons: If someone forward declares something from namespace std, then your code exhibits undefined behavior (but will likely work).
Forward declarations in C++ are useful to save in compile time as the compiler does not need to check for translation units in the included header. Also it has other benefits such as preventing namespace pollution, allowing to use PImpl idiom and it may even reduce the binary size in some cases.
struct
and class
are completely interchangeable as far as forward declarations are concerned. Even for definitions, they only affect the default access specifier of the objects members, everything else is equivalent. You always define "classes" of objects.
The only place where struct
must be used over class
, is when forward declaring opaque data for c bindings.
Regarding your edit:
I know the differences between class/struct regarding default public/private but I'm asking specifically about the forward declarations and possible consequences of swapping them.
Visual C++ produces warning C4099. It does it, because the name decoration for its functions incorporates the keyword you used. Therefore, programs may fail to link properly. So perfectly standard compliant code may not link when using VC++ (A bonehead move on Microsoft's part, AFAIC).
A discussion of this warning, as well as why it can be ignored if you are disciplined, can be found here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With