Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forward declaration as struct vs class

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 
like image 323
Tomas Andrle Avatar asked Nov 22 '16 09:11

Tomas Andrle


People also ask

Can you forward declare a struct?

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

What is forward declaration of a class?

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 }

Is forward declaration good practice?

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

What is the advantage of forward declaration?

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.


1 Answers

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

like image 134
StoryTeller - Unslander Monica Avatar answered Sep 19 '22 14:09

StoryTeller - Unslander Monica