-11

The #include problem

class widget { };

class fubar : public widget { // 1

    void value_parameter(widget); // 2    
    void ref_parameter(widget &); // 3
    void ptr_parameter(widget *); // 4

    virtual void value_parameter(widget); // 5
    virtual void ref_parameter(widget &); // 6
    virtual void ptr_parameter(widget *); // 7

    widget value_return(); // 8
    widget & ref_return(); // 9
    widget * ptr_return(); // 10

    widget instance_value_member; // 11
    widget & instance_ref_member; // 12
    widget * instance_ptr_member; // 13

    static widget static_value_member; // 14
    static widget & static_ref_member; // 15
    static widget * static_ptr_member; // 16
};

Which of those lines require a has include? (#include "widget.hpp")

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 3
    Which lines do you think it is, and why? – NathanOliver May 23 '19 at 13:09
  • The code implies `widget` is provided just before `fubar`, but the rest of the question's text implies the opposite. If its the first case, you don't need the `#include` at all for any of the members (`widget` is already provided). If it's the second, just the fact that you inherit from `widget` means you need the `#include` regardless of the rest of `fubar`'s definition. – François Andrieux May 23 '19 at 13:11
  • 1
    @Sergio Legaz Ruiz You forgot to mark this line class fubar : public widget {..:) – Vlad from Moscow May 23 '19 at 13:12
  • 1
    Welcome to StackOverflow! Please choose a more descriptive title; the title as-is is unlikely to help a future visitor. – AndyG May 23 '19 at 13:16
  • 1
    .... to put it kindly – Lightness Races in Orbit May 23 '19 at 13:17

3 Answers3

5

Full definition of Widget is required for:

  • #1 (class fubar : public widget), we need base class definition.
  • #11 (widget instance_value_member;), we need member definition.

Forward declarations is enough for the others.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
3

None.

class widget { }; defines a complete type.

It would have been a different matter had you written class widget; i.e. a forward class declaration. Then given that you'd need a complete type due to the inheritance, there would be no further #include necessary for the functions.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

I think you mean a forward declaration

class widget;

instead of the definition

class widget { };

In this case the first header line of the class declaration

class fubar : public widget { // 1

requires a complete type definition of widget. Otherwise the size of the class fubar will be unknown.

All other declarations do not require a compete type definition of widget except this line

widget instance_value_member; // 11

Take into account that static data members may have incomplete types because they are declarations in a class definition (except when they are declared with the specifier constexpr). So this line for example

static widget static_value_member; // 14

does not require the complete type definition of widget.

Also you may not overload member functions the following way

void value_parameter(widget); // 2    
void ref_parameter(widget &); // 3
void ptr_parameter(widget *); // 4

virtual void value_parameter(widget); // 5
virtual void ref_parameter(widget &); // 6
virtual void ptr_parameter(widget *); // 7

that is to overload virtual and non-virtual functions with the same names and parameter lists.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335