0

I have a header with forward-declared classes that I want to declare some smart pointer members in. However, since the smart pointer template types are technically incomplete at time of declaration, I'm getting compilation errors regarding sizeof not being able to be used for unique pointers. Do I have to pull in the implementation headers into my class's header, rather than forward-declaring them, or is there an additional stub I can provide to my forward declaration that will satisfy the smart pointers?

For instance, this is the header file:

#include <memory>

namespace N {
    class A;
    class Owner {
        std::unique_ptr<A> myMember;
    }
}

And this is the source file:

#include "A.H"

class Owner{
    Owner() {
        myMember = std::make_unique<A>("arg1", "arg2");
    }
}

I'd rather not bleed dependencies to everyone who includes my header, which is why the classes were originally forward declared when I was using raw pointers.

  • Please paste the error message – Serial Lazer Nov 07 '20 at 03:37
  • Does this answer your question? [Is std::unique\_ptr required to know the full definition of T?](https://stackoverflow.com/questions/6012157/is-stdunique-ptrt-required-to-know-the-full-definition-of-t) – mlt Nov 07 '20 at 03:37

1 Answers1

2

How can I declare smart pointers in a header file with incomplete forward-declared classes?

By defining the constructor, destructor and other functions that depend on complete definition of the pointed class outside of the header and within a separate translation unit.

Do I have to pull in the implementation headers into my class's header

No. That is only necessary if you don't define the member functions outside of the class definition as I described.


Example:

struct Owner {
    std::unique_ptr<A> myMember;

    Owner();
    ~Owner();
    Owner(Owner&&);
    Owner& operator=(Owner&&);
};

class A {};

Owner::Owner() = default;
Owner::~Owner() = default;
Owner::Owner(Owner&&) = default;
Owner& Owner::operator=(Owner&&) = default;
eerorika
  • 181,943
  • 10
  • 144
  • 256
  • I realized after posting my question that I actually had `~Owner() = default` in the header. Do I need to just have an empty destructor in the source file, rather than letting the compiler generate it within the header? – cabbagesoup Nov 07 '20 at 04:19
  • @cabbagesoup Yes. – eerorika Nov 07 '20 at 04:20