0

I am learning c++ and confused about the ways to include another class in current class. For example, I am wondering whether class QuackBehavior equals to #include <QuackBehavior.h>. If they are equal, what are the differences between these two ways? The code is :

#include <string>

class QuackBehavior;

class Duck {
public:
    Duck();
    virtual ~Duck() {};

    virtual void performQuack();

    virtual std::string getDescription() = 0;

    std::string getName() {return m_name;}
    void setName(std::string name ) {m_name = name;}
    void setQuackBehavior(QuackBehavior * behavior);

protected:
    std::string m_name;
    QuackBehavior * m_quackBehavior;

};

Thank you so much.

Xiufen Xu
  • 531
  • 1
  • 3
  • 19
  • 2
    The `class QuackBehavior;` line is a forward declaration — 'there exists a class called `QuackBehavior`'. It is sufficient to let a client of `class Duck` compile without including `` — which speeds up compilation. It won't be enough for implementing the quack behaviour, though. – Jonathan Leffler Oct 25 '16 at 05:18
  • 1
    This may help you understand forward declarations: http://stackoverflow.com/questions/4757565/c-forward-declaration – Retired Ninja Oct 25 '16 at 05:18
  • @JonathanLeffler That makes sense. Thank you so much. – Xiufen Xu Oct 25 '16 at 05:37
  • @RetiredNinja Hey Ninja, your link is really helpful, thank you so much! – Xiufen Xu Oct 25 '16 at 05:37
  • @JonathanLeffler I am wondering does the compiler will go to look for the `QuackBehavior.h` file or not if I just write `class QuackBehavior`. Thank you – Xiufen Xu Oct 25 '16 at 05:40
  • 1
    If you don't say `#include "QuackBehavior.h"` or `#include `, the compiler won't go looking to include the file. For all it knows, the details are in `Queen-of-Sheba.h` anyway. The header name being the class name plus `.h` is merely conventional. – Jonathan Leffler Oct 25 '16 at 05:43
  • @JonathanLeffler I see, thank you so much! – Xiufen Xu Oct 25 '16 at 05:45

2 Answers2

1

In QuackBehavior.h file, forwarding declaring QuackBehavior class will suffice.

#include <string>

class QuackBehavior; // tells the compiler that a class called QuackBehavior exists without any further elaborations

class Duck {
 public:
   Duck();
   virtual ~Duck() {};

   virtual void performQuack();

   virtual std::string getDescription() = 0;

   std::string getName() {return m_name;}
   void setName(std::string name ) {m_name = name;}
   void setQuackBehavior(QuackBehavior * behavior);

  protected:
   std::string m_name;
   QuackBehavior * m_quackBehavior;
};

However in QuackBehavior.cpp file, you have to use #include"QuackBehavior.h" so that the compiler can find the implementation member functions

#include <QuackBehavior.h> 
#include <string>
duck::duck()
{
}
seccpur
  • 4,996
  • 2
  • 13
  • 21
1

The two are not equal:

class QuackBehavior; is considered a forward-declaration, and simply informs the compiler that there is a class called QuackBehavior. This can only be used if you are using QuackBehavior as a pointer or reference:

class B;
struct C;
struct A
{
    shared_ptr<B> getB() const { return b; }
    const C& getC() const;
private:
    shared_ptr<B> b;
};

Here the compiler doesn't need to know any implementation details of C and B, only that they exist. Notice that it's important to tell the compiler whether it's a class or struct also.

#include <QuackBehavior> is an include, and essentially copies+pastes the entire file into your file. This allows the compiler and linker to see everything about QuackBehavior. Doing this is slower, as you'll then include everything that QuackBehavior includes, and everything those files include. This can increase compile times dramatically.

Both are different, and both have their places:

  • Use forward-declaration when you don't need to know the implementation details of a class just yet, only that they exist (e.g. use in pointers and references)
  • Include the file if you are declaring an object, or you need to use functions or members of a class.
Tas
  • 7,023
  • 3
  • 36
  • 51