How to forward declare a class to be used in a standard container of unique_ptr

孤者浪人 提交于 2019-12-11 02:25:39

问题


Is it possible to avoid having full class definition visible when using it in standard container of smart pointers? For example I can't get the following to compile:

#include <memory>
#include <map>
class Foo;
class Bar {
public:
   Bar();    
   std::map<int, std::unique_ptr<Foo>> myMap;
};

The Clang compiler seems to insist on having full definition of Foo available when compiling Bar. Is there a technique I could use to avoid having to include Foo.h?

Edit1:

error: invalid application of 'sizeof' to an incomplete type 'Foo':
  static_assert(sizeof(_Tp) > 0, "default_delete can not delete incomplete type");

Edit2: No it is not a duplicate of is std::unique_ptr required to know the full definition. Just using unique_ptr does not necessarily requires full definition, but using it inside of standard container introduces additional wrinkles.

Edit3: It turns out I can achieve (almost) what I want by introducing a base class with a virtual destructor. Then a class that has a container of smart pointers to base class will compile w/o a problem. Nothing else has to be present in base class and base class must be fully visible. This way all complexities of derived classes may be hidden when container is compiled.


回答1:


Even though strict forward declaration would not compile a container of smart pointers, it is still possible to solve most practical needs and avoid exposing a complete class when defining a user class with a container. Just introduce a base class with public virtual distractor and have it visible.

in fooBase.h

class FooBase {
   public virtual ~FooBase();
};

in bar.h

 #include "foobase.h"
 #include <memory>
 #include <map>
 class Bar {
    ...
    std::map<int, std::unique_ptr<FooBase>> myMap;
 }

When Foo is derived from FooBase and placed in its own header file changes to Foo would no longer necessitate recompilations of Bar.




回答2:


You have yo make the Foo destructor and constructors public. IF you are having othe errors please post them, since it is hard to tel from your initial post. The following code compiles:

#include <memory>
#include <map>

class Foo;

class Bar {
    public:
        Bar () {};
        std::map<int, std::unique_ptr<Foo> > myMap;
};

class Foo {
    public:
         Foo () {};
         ~Foo () {};

    };

int main ()
{
    Bar b;
}

EDIT: check these other posts: Forward declaration with unique_ptr?
Is std::unique_ptr<T> required to know the full definition of T?



来源:https://stackoverflow.com/questions/25795363/how-to-forward-declare-a-class-to-be-used-in-a-standard-container-of-unique-ptr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!