- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
这是我尝试将 unique_ptr 用于 pimpl 时所看到的简化。我选择 unique_ptr 是因为我真的希望类拥有指针 - 我希望 pimpl 指针和类的生命周期相同。
不管怎样,这是标题:
#ifndef HELP
#define HELP 1
#include <memory>
class Help
{
public:
Help(int ii);
~Help() = default;
private:
class Impl;
std::unique_ptr<Impl> _M_impl;
};
#endif // HELP
这里是来源:
#include "Help.h"
class Help::Impl
{
public:
Impl(int ii)
: _M_i{ii}
{ }
private:
int _M_i;
};
Help::Help(int ii)
: _M_impl{new Help::Impl{ii}}
{ }
我可以将它们编译成一个库就好了。但是当我尝试在测试程序中使用它时,我得到了
ed@bad-horse:~/ext_distribution$ ../bin/bin/g++ -std=c++0x -o test_help test_help.cpp Help.cpp
In file included from /home/ed/bin/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/memory:86:0,
from Help.h:4,
from test_help.cpp:3:
/home/ed/bin/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h: In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = Help::Impl]':
/home/ed/bin/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:245:4: required from 'void std::unique_ptr<_Tp, _Dp>::reset(std::unique_ptr<_Tp, _Dp>::pointer) [with _Tp = Help::Impl; _Dp = std::default_delete<Help::Impl>; std::unique_ptr<_Tp, _Dp>::pointer = Help::Impl*]'
/home/ed/bin/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:169:32: required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = Help::Impl; _Dp = std::default_delete<Help::Impl>]'
Help.h:6:7: required from here
/home/ed/bin/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:63:14: error: invalid application of 'sizeof' to incomplete type 'Help::Impl'
这是众所周知的safety feature .我已经尝试过。
我的问题是,如果我将 Help::Impl 声明放在标题中,它似乎会消除 pimpl 的任何优势。类布局对用户可见。定义是隐藏的,但我可以使用 Help 类和私有(private)成员来做到这一点。此外,包括 Impl 的声明带来了新的 header ,我希望将它们分开。
我错过了什么?人们在 Impl 声明中添加了什么以及在哪里?我做错了 Help dtor 吗?啊!
最佳答案
我相信您的 test_help.cpp 实际上看到了您声明默认的 ~Help()
析构函数。在该析构函数中,编译器也尝试生成 unique_ptr
析构函数,但它需要 Impl
声明。
所以如果你把析构函数定义移到Help.cpp,这个问题应该就没有了。
-- 编辑--您也可以在 cpp 文件中定义析构函数为默认值:
Help::~Help() = default;
关于c++ - 如何将 unique_ptr 用于 pimpl?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9020372/
我有两个实现 PIMPL 的类:State 和 StateMachine。 它们实现了 Private::State 和 Private::StateMachine。 Private::StateMa
考虑以下两种实现 pimpl 习语的方法: // file g_visible.h //global forward declarations class HiddenStuff_A; class
我目前正在研究pimpl idiom,并且有非常好的教程介绍如何实现它(例如 here )。但我从未见过它像这样作为基本模板类实现: #ifndef PIMPL_H #define PIMPL_H t
这个问题在这里已经有了答案: Move semantics == custom swap function obsolete? (5 个答案) 关闭 2 年前。 我有几个基于 PIMPL 习语的类(
我正在开发一个小型 IO 库,其中接口(interface)的要求是已知的,但实现可能会发生变化。该库应该以存档格式读取和写入文件,并存储一些元数据。 我考虑过使用 pimpl,因为它似乎非常适合这项
我正在尝试为 pimpl idiom 创建一个实用程序类,但是我遇到了一些问题,希望得到一些帮助: 这就是我得到的: [sehe:另请参阅此处的 rev.1:https://gist.github.c
请看下面的代码(一代码胜一千字): 形状.hpp class Shape { public: double area() const; private: class ShapeImpl
我想更好地理解如何在 PIMPL 习语存在的情况下使用静态字段方法。考虑以下代码。 MyClass.h 文件: #ifndef MYCLASS #define MYCLASS class MyClas
假设我有一个 B 类型的对象,并调用 B.foo(),其中 foo() 是定义的方法在 A 中并且尚未在 B 中重新定义。 A::foo() 有 impl->foo() 行。 当我们调用 B.foo(
我正在从 http://en.wikibooks.org/wiki/C%2B%2B_Programming/Code/Design_Patterns#Creational_Patterns 中阅读有关
我正在使用 pimpl 惯用法实现几个类,并且遇到了一些设计问题。 首先,我一直看到pimpl是这样做的 class Object { public: Visible(); ~Visi
.h public: void doStuff() const; private: struct Private; Private * d; .cpp struct XX::P
所以我一直在思考PIMPL和堆栈分配。我一直在编写一个库,并决定使用 PIMPL 来隐藏该类的私有(private)成员。这意味着我将有一个这样声明的类 class Foo { private:
我正在尝试使用 pimpl 模式并在匿名命名空间中定义实现类。这在 C++ 中可能吗?我失败的尝试如下所述。 是否可以在不将实现移动到具有名称(或全局名称)的 namespace 的情况下解决此问题?
考虑以下几点: PImpl.hpp class Impl; class PImpl { Impl* pimpl; PImpl() : pimpl(new Impl) { } ~
可以使用什么样的技巧来最小化实现 pImpl 类的工作量? 标题: class Foo { struct Impl; boost::scoped_ptr self; public:
请参阅我的 PIMPL 继承实现。在派生类中,DerivedImpl继承自BaseImpl。 问题:指向 Impl 的指针是否应该像下面的代码一样只在基类中定义?如果是这样,每次我需要使用基指针时,我
这是一个非常愚蠢的错误,但我不知道这里发生了什么。 有很多 pimpl 示例,但我不明白为什么这不起作用(这或多或少是示例之一,但我看不出有什么区别)。 我有一个非常简单的 Pimpl 示例,但它不起
在我的新工作场所,代码大量使用 Pimpl 惯用语,原因是为了减少编译时间。但是我有一个基本的查询——pimpl 不需要动态分配内存吗?因此,实际上我们在堆中分配了比需要更多的内存。如果它被大量使用,
考虑下一个简单的例子: 标题: // a.hpp #ifndef A_HPP #define A_HPP #include class A { public: A(); int foo()
我是一名优秀的程序员,十分优秀!