相关疑难解决方法(0)

我什么时候可以使用前瞻性声明?

我正在寻找允许在另一个类的头文件中进行类的前向声明的定义:

我是否允许为基类,作为成员持有的类,通过引用传递给成员函数的类等执行此操作?

c++ c++-faq forward-declaration

588
推荐指数
7
解决办法
23万
查看次数

具有不完整类型的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万
查看次数

使用unique_ptr进行前向声明?

我发现std::unique_ptr在下面的代码中结合使用前向声明类很有用.它编译并与GCC一起工作,但整个事情似乎有点奇怪,我想知道这是否是标准行为(即标准要求)?因为B声明时B不是完整的类型unique_ptr.

A.hpp

#include <memory>

class B;

class A {
    std::unique_ptr<B> myptr;
    // B::~B() can't be seen from here
public:
    ~A();
};
Run Code Online (Sandbox Code Playgroud)

A.cpp

#include "B.hpp"
//B.hpp has to be included, otherwise it doesn't work.

A::~A() = default; // without this line, it won't compile 
// however, any destructor definiton will do.
Run Code Online (Sandbox Code Playgroud)

我怀疑这与析构函数有关(因此需要调用析构函数unique_ptr<B>)是在特定的编译单元(A.cpp)中定义的.

c++ destructor forward-declaration unique-ptr

62
推荐指数
1
解决办法
3万
查看次数

我如何使用unique_ptr用于pimpl?

这是我在尝试将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
Run Code Online (Sandbox Code Playgroud)

这是来源:

#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}}
{ }
Run Code Online (Sandbox Code Playgroud)

我可以将它们编译成一个库就好了.但是当我尝试在测试程序中使用它时,我得到了

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 = …
Run Code Online (Sandbox Code Playgroud)

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

60
推荐指数
2
解决办法
2万
查看次数

我应该使用shared_ptr还是unique_ptr

我一直在使用pimpl成语制作一些对象,但我不确定是否使用std::shared_ptrstd::unique_ptr.

据我所知,std::unique_ptr是更有效的,但是这是没有这么多的问题,对我来说,因为这些物体是比较重量级反正做的成本std::shared_ptrstd::unique_ptr相对较小.

我目前std::shared_ptr只是因为额外的灵活性.例如,使用a std::shared_ptr允许我将这些对象存储在散列映射中以便快速访问,同时仍然能够将这些对象的副本返回给调用者(因为我相信任何迭代器或引用可能很快变得无效).

但是,这些对象确实没有被复制,因为更改会影响所有副本,所以我想知道也许使用std::shared_ptr和允许副本是某种反模式或坏事.

它是否正确?

c++ pimpl-idiom shared-ptr unique-ptr c++11

52
推荐指数
3
解决办法
2万
查看次数

Pimpl - 为什么可以在不完整的类型上调用make_unique

为什么make_unique调用编译?make_unqiue不要求其模板参数是完整类型吗?

struct F;
int main()
{
  std::make_unique<F>();
}

struct F {};
Run Code Online (Sandbox Code Playgroud)

从orignated问题我的"问题"与我PIMPL实现:

我确实理解为什么析构函数必须在用户声明并在实现类(PIMPL)的cpp文件中定义.

但是移动包含pimpl的类的构造函数仍会编译.

class Object
{};

class CachedObjectFactory
{
public:
  CachedObjectFactory();

  ~CachedObjectFactory();
  std::shared_ptr<Object> create(int id) const;

private:
  struct CacheImpl;
  std::unique_ptr<CacheImpl> pImpl;
};
Run Code Online (Sandbox Code Playgroud)

现在cpp文件:

// constructor with make_unique on incompete type ?
CachedObjectFactory::CachedObjectFactory()
  : pImpl(std::make_unique<CacheImpl>())
{}

struct CachedObjectFactory::CacheImpl
{
  std::map<int, std::shared_ptr<Object>> idToObjects;
};

//deferred destructor
CachedObjectFactory::~CachedObjectFactory() = default;
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么这个编译?为什么建筑和破坏之间存在差异?如果析构函数的实例化和default_deleter的实例化是一个问题,为什么make_unique的实例化不是问题?

c++ templates pimpl-idiom unique-ptr language-lawyer

26
推荐指数
2
解决办法
1134
查看次数

Unique_ptr和前向声明

说我有两个班:

"foo.h中"

#pragma once    
class Foo
{
public:
    Foo()
    {

    };

    ~Foo()
    {

    };
};
Run Code Online (Sandbox Code Playgroud)

"啊"

#pragma once
#include <memory>

class Foo;

class A
{
public:
    A(){};
    ~A(){};

    std::unique_ptr<Foo> foo;
};
Run Code Online (Sandbox Code Playgroud)

A持有unique_ptrFoo.我不想包含Foo在"啊"中,所以我向前宣布它.通过Foo在"Ah"中向前声明类,我得到一个编译时错误:

error C2027: use of undefined type 'Foo'
error C2338: can't delete an incomplete type  
Run Code Online (Sandbox Code Playgroud)

所以我下面这个文章就如何避免这种错误,并在它自己的.cpp文件,我还包括富移动A的析构函数:

"A.cpp"

#include "A.h"

#include "Foo.h"

A::A()
{

}

A::~A()
{

}
Run Code Online (Sandbox Code Playgroud)

在"A.cpp"中实现A的析构函数后,我能够编译程序,因为类Foo在"A.cpp"中已知.这似乎是合乎逻辑的,因为unique_ptr需要完整的类型来调用它的析构函数.但令我惊讶的是,在评论出A的构造函数(在"Ah"以及"A.cpp"中)后,我得到了同样的错误.这怎么可能?为什么编译器抱怨在A没有构造函数时无法调用Foo的析构函数?

编辑:我上传了4个文件,以便您可以测试该程序.我正在使用Visual Studio 2013的MSVC++.

http://www.filedropper.com/test_61

c++ c++11

16
推荐指数
2
解决办法
7596
查看次数

std :: vector的不完整类型

当我尝试以下操作时,GCC编译器会抱怨(见下文).class Face需要不完整,因为它包含指向class Element同样包含指针的指针class Face.换句话说,类之间存在循环依赖关系.我该如何解决?

错误:'sizeof'无效应用于不完整类型'Face'

class Face; // needs to be incomplete

class Element
{
    std::vector < std::unique_ptr <Face> > face;
};

class Face
{
    std::vector < std::unique_ptr <Element> > elm;
};
Run Code Online (Sandbox Code Playgroud)

c++ containers smart-pointers incomplete-type

10
推荐指数
1
解决办法
3016
查看次数

我应该在主要不是容器上使用shared_ptr或weak_ptr吗?

我有两个标准容器.它们都指向相同的数据结构.第一个包含所有数据,第二个包含一些相同的数据.我应该使用shared_ptrweak_ptr在第二个容器上?

首先,当我阅读我想unique_ptr在第一个集合上使用的参考时.我的第一个集合包含所有数据,它是唯一一个"拥有"的数据.这意味着如果数据不存在,则应将其删除.但是当我尝试创建第二个集合时,我不知道该怎么做.我创建了一个唯一的指针,但现在我需要另一个指向同一元素的指针来破坏唯一性,但事实上真正的所有者并不是新的指针.所以我理解(我希望我没有错),唯一性是在达到元素的方式而不是(例如)删除元素的可能性.所以,shared_ptr.我在他的第一个系列中有它们.但是现在第二个出现了,我想用了shared_ptr这里也.访问相同数据的方式可能都是,因此所有者是两个.但在我的情况下,数据总是从之前的第二个删除.如果我使用a weak_ptr,所有者的数量不会增加.在这两种情况下,当第一个集合需要时,元素将被删除.最后我正在使用shared_ptr因为weak_ptr我需要lock()每行代码中的每个指针,使其可读性降低.但我应该真正使用什么?

c++ smart-pointers c++11

9
推荐指数
2
解决办法
1171
查看次数

为什么"错误:使用unique_ptr将'sizeof'无效应用于不完整类型"通过添加空析构函数来修复?

我正在上课STFT.在标题中编译就好了:

class STFT; // pimpl off to prevent point name clash

class Whatever
{
private:
    STFT* stft;
Run Code Online (Sandbox Code Playgroud)

这在实施中:

#include "STFT.h"
Whatever::Whatever() : stft(new STFT()) {
// blah blah
}

Whatever::~Whatever() {
    delete stft; // pure evil
}
Run Code Online (Sandbox Code Playgroud)

但是,切换到std::unique_ptr<STFT> stft;标题中的原始指针,并删除析构函数,我得到

错误:'sizeof'无效应用于不完整类型'STFT'static_assert(sizeof(_Tp)> 0,"default_delete无法删除不完整类型");

但是,如果我只提供一个空的析构函数Whatever::~Whatever(){},那么它编译得很好.这让我完全难过.请填写我这个毫无意义的析构函数为我做的事情.

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

9
推荐指数
2
解决办法
6329
查看次数