相关疑难解决方法(0)

具有不完整类型的std :: unique_ptr将无法编译

我正在使用pimpl-idiom std::unique_ptr:

class window {
  window(const rectangle& rect);

private:
  class window_impl; // defined elsewhere
  std::unique_ptr<window_impl> impl_; // won't compile
};
Run Code Online (Sandbox Code Playgroud)

但是,我在第304行的第304行收到有关使用不完整类型的编译错误<memory>:

' sizeof'到不完整类型' uixx::window::window_impl的应用无效' '

据我所知,std::unique_ptr应该可以使用不完整的类型.这是libc ++中的错误还是我在这里做错了什么?

c++ unique-ptr incomplete-type libc++

179
推荐指数
5
解决办法
5万
查看次数

GotW#101"解决方案"实际上解决了什么问题吗?

首先阅读Herb's Sutters GotW关于C++ 11中pimpl的帖子:

我在理解GotW#101中提出的解决方案时遇到了一些麻烦.据我所知,在GotW#100中辛苦解决的所有问题都复仇了:

  • pimpl成员是外的线的模板,并且定义并不在使用点可见(在class widget的类定义和隐式生成的特殊成员函数widget).也没有任何明确的实例化.这将导致链接期间未解决的外部错误.

  • widget::impl实例化定义的点上仍然是不完整的(我认为它实际上根本没有pimpl<widget::impl>::~pimpl()实例化,只是被引用).因此std::unique_ptr<widget::impl>::~unique_ptr()调用delete指向不完整类型的指针,如果widget::impl有一个非平凡的析构函数,则会产生未定义的行为.

请解释是什么迫使编译器在widget::impl完成的上下文中生成特殊成员.因为我看不出它是如何工作的.


如果GotW#101仍然需要widget::~widget()在实现文件中明确定义,哪里widget::impl完成,那么请解释"更健壮"的评论(@sehe在他的答案中引用).

我看的GotW#101的核心要求是,包装"消除样板的一些作品",这在我看来(基于该段的其余部分)来表示的widget::~widget()声明和定义.所以请不要依赖于你的答案,在GotW#101中,那已经消失了!


Herb,如果你停下来,请告诉我是否可以在这里剪切+粘贴解决方案代码以供参考.

c++ pimpl-idiom incomplete-type c++11 gotw

21
推荐指数
2
解决办法
1856
查看次数

这是在C++ 11中实现pimpl wth unique_ptr和move-semantics的正确方法

我还没有看到一个同时使用unique_ptr和move-semantics的pimpl示例.

我想将一个CHelper类添加到STL派生容器中,并使用pimpl来隐藏CHelper所做的事情.

这看起来不错吗?

Derived.h

class CDerived : public set<CSomeSharedPtr>, public CHelper  
{
//...
};
Run Code Online (Sandbox Code Playgroud)

`

Helper.h

// derived containers need to support both copy and move, so CHelper does too  

class CHelper  
{  
private:  
    class impl;  
    unique_ptr<impl> pimpl;  

public:  
//--- default: need both cotr & cotr (complete class) in order to use unique_ptr<impl>  
    CHelper();  
    ~CHelper();  

//--- copy  
    CHelper(const CHelper &src);         //copy constructor  
    CHelper& operator=(const CHelper &src);//assignment operator  

//--- move  
    CHelper(CHelper &&src);         //move constructor  
    CHelper& operator=(CHelper &&src);//move operator  

//--- expose public …
Run Code Online (Sandbox Code Playgroud)

c++ unique-ptr c++11

9
推荐指数
1
解决办法
4475
查看次数

有没有办法结合编译器防火墙(Pimpl)和默认可复制性的好处?

假设我有一个私有成员的类,这是该类客户端不关心的实现细节.这个类是一个值类型,我们希望它是可复制的,例如

#include <boost/bimap.hpp>  // some header that pulls in many other files

class MyClass {
public:
    MyClass() {}
    ...
private:
    boost::bimap<Key,Value>   table;
};
Run Code Online (Sandbox Code Playgroud)

现在,MyClass的每个客户端都被迫引入了许多不需要的升级头,增加了构建时间.但是,该课程至少是可复制的.

如果我们引入编译器防火墙(Pimpl idiom),那么我们可以将#include依赖项移动到cpp文件,但是由于规则5,我们现在必须做更多的努力工作:

// no extra #includes - nice
class MyClass {
public:
    MyClass() {}
    // ugh, I don't want this, just make it copyable!
    MyClass(const MyClass& rhs);
    MyClass(MyClass&& rhs);
    MyClass& operator=(const MyClass& rhs);
    MyClass& operator=(MyClass&& rhs);
    ~MyClass() {}
    ...
private:
    std::unique_ptr<MyClassImpl>  impl;
};
Run Code Online (Sandbox Code Playgroud)

是否有一种技术可以获得编译器防火墙的好处,但保留可复制性,以便我不需要包含5的规则样板?

c++ pimpl-idiom

5
推荐指数
1
解决办法
509
查看次数

包含一个以 std::unique_ptr&lt;T&gt; 作为字段的类,而“T”是不完整类型

std::unique<B>我为incomplete type创建了一个小测试用例B

测试.h

#pragma once
#include <memory>
class B;   //<--- compile error here
class Test{
    std::unique_ptr<B> bPtr;   
    //#1 need to move destructor's implementation to .cpp
    public: ~Test();
};
Run Code Online (Sandbox Code Playgroud)

测试.cpp

#include "Test.h"
class B{};
Test::~Test(){}  //move here because it need complete type of B
Run Code Online (Sandbox Code Playgroud)

主程序

#include <iostream>
#include "Test.h"
using namespace std;
int main(){
   Test test;
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

我收到此错误:-

/usr/include/c++/4.8.2/bits/unique_ptr.h:65:22:错误:“sizeof”对不完整类型“B”的无效应用

据我了解,编译器告诉我这 B是一个不完整的类型(in main.cpp),因此它无法B正确删除。

但是,在我的设计中,我不想main.cpp拥有完整B.
粗略地说,这是一个粉刺。

有没有好的解决方法?

这里有一些类似的问题,但没有一个提出干净的解决方法。 …

c++ pimpl-idiom unique-ptr incomplete-type c++11

5
推荐指数
0
解决办法
184
查看次数

执行 PIMPL 时如何避免共享指针开销

AFAIKunique_ptr与 PIMPL 一起使用非常棘手,因为删除器是unique_ptr类型的一部分,因此它不适用于不完整的类型。另一方面,shared_ptr使用动态删除器,因此它可以处理不完整的类型。

shared_ptr无论我是否需要,都存在给我原子操作的性能问题。

我可以使用其他更快的替代方案吗std::?我显然对类型擦除很满意,我说的是原子引用计数的成本。

#include <any>
#include <memory>
#include <iosfwd>

std::shared_ptr<std::fstream> sp;
// unique_ptr requires complete type
// std::unique_ptr<std::fstream> up;
std::any a;

#include <fstream>
int main() {
    // any requires copy_constructible
    // a = std::fstream{};  
    sp = std::make_shared<std::fstream>();
} 
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 我考虑过any,但它不适用于某些类型。
  • 我考虑使用动态删除器的 unique_ptr ,但据我所知构造unique_ptr函数永远不会“告诉”删除器构造的对象是什么(为删除器提供一种学习如何销毁对象的方法)。

PS 我知道很久以前boost::shared_ptr就有宏来禁用原子引用计数,但即使仍然支持我也不想切换到boost::shared_ptr.

c++ pimpl-idiom shared-ptr c++20

-1
推荐指数
1
解决办法
285
查看次数