如何转发声明一个类在unique_ptr的标准容器中使用 [英] How to forward declare a class to be used in a standard container of unique_ptr

查看:771
本文介绍了如何转发声明一个类在unique_ptr的标准容器中使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当在智能指针的标准容器中使用它时,是否可以避免使完整的类定义可见?例如我不能得到以下编译:

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

Clang编译器似乎坚持拥有 Foo 在编译 Bar 时可用。是否有一种技术可以避免包含Foo.h?

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:不是是std :: unique_ptr,了解完整定义。只是使用unique_ptr不一定需要完全定义,但使用它在标准容器内引入额外的皱纹。

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:事实证明,我可以通过引入一个带虚拟析构函数的基类实现(几乎)我想要的。然后一个类有一个智能指针容器基类将编译w / o一个问题。基类中不需要有其他东西,基类必须完全可见。这样,当编译容器时,派生类的所有复杂性都可能被隐藏。

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.

推荐答案

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

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.

在fooBase.h中

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

当Foo派生自FooBase并放在自己的头文件中时,将不再需要重新编译Bar。

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

这篇关于如何转发声明一个类在unique_ptr的标准容器中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆