如何转发声明要在unique_ptr的标准容器中使用的类

时间:2014-09-11 19:10:49

标签: c++ c++11 smart-pointers forward-declaration

在智能指针的标准容器中使用它时,是否可以避免显示完整的类定义?例如,我无法得到以下内容进行编译:

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

Clang编译器似乎坚持在编译Foo时可以使用Bar的完整定义。是否有一种技术可以避免包含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:不,它不是is std::unique_ptr required to know the full definition的副本。仅使用unique_ptr并不一定需要完全定义,但在标准容器内使用它会引入额外的皱纹。

Edit3:事实证明,我可以通过引入带有虚拟析构函数的基类来实现(几乎)我想要的东西。然后,一个具有基类智能指针容器的类将编译没有问题。基类中不得出现任何其他内容,基类必须完全可见。这样,在编译容器时,可能会隐藏派生类的所有复杂性。

2 个答案:

答案 0 :(得分:0)

尽管严格的前向声明不会编译智能指针的容器,但仍然可以解决大多数实际需求,并避免在使用容器定义用户类时暴露完整的类。只需介绍一个带有公共虚拟干扰器的基类,并让它可见。

在fooBase.h中

class FooBase {
   public virtual ~FooBase();
};
在bar.h中

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

当Foo从FooBase派生并置于其自己的头文件中时,对Foo的更改将不再需要重新编译Bar。

答案 1 :(得分:-1)

你要让Foo析构函数和构造函数公开。如果您遇到其他错误,请发布,因为很难从您的初始帖子发送电话。以下代码编译:

#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;
}

编辑:查看以下其他帖子: Forward declaration with unique_ptr?
Is std::unique_ptr<T> required to know the full definition of T?