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

标签 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 编译器似乎坚持在编译 Bar 时提供完整的 Foo 定义。有没有一种技术可以用来避免必须包含 Foo.h?

编辑1:

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:事实证明,我可以(几乎)通过引入一个带有虚拟析构函数的基类来实现我想要的。然后,一个包含指向基类的智能指针容器的类将在没有问题的情况下进行编译。基类中不必存在任何其他内容,并且基类必须完全可见。这样,在编译容器时可以隐藏派生类的所有复杂性。

最佳答案

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

在 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。

关于c++ - 如何转发声明要在 unique_ptr 的标准容器中使用的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25795363/

相关文章:

c++ - 用智能指针实现一个简单的单向链表

c++ - 这个检测循环链表的函数的时间复杂度是多少?

c++ - 何时在 C++ 中使用字符数组而不是字符串?

c++ - 我应该将 C++11 emplace_back 与指针容器一起使用吗?

c++ - 指针有拷贝构造函数吗?

rust - 遍历中RefCell的循环引用借用

c++ - std::string 的对象真的可以 move 吗?

c++ - 在 C++ 中使用 const ArrayType 或 ConstArrayType typedef 具有 const 元素的数组

c++ - 这个奇怪的复制构造函数错误在提示什么?

gcc - 为什么 GCC std::atomic 增量会产生低效的非原子组装?