相关疑难解决方法(0)

是否需要std :: unique_ptr <T>才能知道T的完整定义?

我在头文件中有一些代码如下:

#include <memory>

class Thing;

class MyClass
{
    std::unique_ptr< Thing > my_thing;
};
Run Code Online (Sandbox Code Playgroud)

如果我有一个CPP这个头不包含的Thing类型定义,那么这并不在VS2010 SP1的编译:

1> C:\ Program Files(x86)\ Microsoft Visual Studio 10.0\VC\include\memory(2067):错误C2027:使用未定义类型'Thing'

替换std::unique_ptrstd::shared_ptr和编译.

所以,我猜这是当前VS2010 std::unique_ptr的实现,需要完整的定义,而且完全依赖于实现.

或者是吗?它的标准要求中是否有某些东西使得std::unique_ptr实施只能使用前向声明?感觉很奇怪,因为它应该只有一个指针Thing,不应该吗?

c++ stl visual-studio-2010 unique-ptr c++11

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

将std :: make_unique与自定义删除器一起使用

在使用std::unique_ptr自定义删除器时,我希望使用std::make_unique而不是原始的新删除器.我正在使用VC++ 2013.在我看来,std::unique_ptr如果您使用自定义删除器,则无法使用.我错过了什么,或者这是真的吗?


附加信息:

我正在使用a std::unique_ptr<HANDLE, custom_deleter>来保存打开的COM端口的Windows HANDLE.

我可以为此编写一个自定义RAII类,它不会非常困难,但我看到它的使用难度/难度/难度std::unique_ptr.

c++ c++11 c++14

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

为什么,真的,删除不完整的类型是未定义的行为?

考虑用来解释一下这个典型的例子并不与前向声明做:

//in Handle.h file
class Body;

class Handle
{
   public:
      Handle();
      ~Handle() {delete impl_;}
   //....
   private:
      Body *impl_;
};

//---------------------------------------
//in Handle.cpp file

#include "Handle.h"

class Body 
{
  //Non-trivial destructor here
    public:
       ~Body () {//Do a lot of things...}
};

Handle::Handle () : impl_(new Body) {}

//---------------------------------------
//in Handle_user.cpp client code:

#include "Handle.h"

//... in some function... 
{
    Handle handleObj;

    //Do smtg with handleObj...

    //handleObj now reaches end-of-life, and BUM: Undefined behaviour
} 
Run Code Online (Sandbox Code Playgroud)

我从标准中了解到这个案例正朝向UB,因为Body的析构函数是非常重要的.我想要了解的是这个的根本原因.

我的意思是,问题似乎是由Handle的dtor内联的事实"触发",因此编译器执行类似下面的"内联扩展"(这里几乎是伪代码).

inline Handle::~Handle()
{ …
Run Code Online (Sandbox Code Playgroud)

c++ destructor memory-management forward-declaration delete-operator

25
推荐指数
3
解决办法
8260
查看次数

Pimpl with smart ptr - 为什么需要构造函数/析构函数

让我们考虑以下示例(使用c ++ 11)

A.hpp:

#include <memory>
class A
{
  public:
    //A();
    //~A();

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

main.cpp中:

#include "A.hpp"

int main()
{
    A a;
}
Run Code Online (Sandbox Code Playgroud)

使用默认构造函数和析构函数.不编译.发生以下错误:

在文件中包含/usr/include/c++/4.8/memory:81:0,来自A.hpp:2,来自main.cpp:2:/usr/include/c++/4.8/bits/unique_ptr.h:实例化'void std :: default_delete <_Tp> :: operator()(_ Tp*)const [with _Tp = A :: AImpl]':/ usr /include/c++/4.8/bits/unique_ptr.h:184:16: 'std :: unique_ptr <_Tp,_Dp> ::〜unique_ptr()[与_Tp = A :: AImpl; _Dp = std :: default_delete]'A.hpp:3:7:从这里需要/usr/include/c++/4.8/bits/unique_ptr.h:65:22:错误:'sizeof'无效应用于不完整类型' A :: AImpl'static_assert
(sizeof(_Tp)> 0,

使用boost :: scoped_ptr而不是std :: unique_ptr时会发生类似的错误.我是否理解正确 - 这意味着,AImpl的前向声明是不够的?

添加构造函数和析构函数时,一切正常.是什么原因?是因为默认是内联的,因此看不到AImpl的大小?在添加构造函数和析构函数时,编译器假定这些定义知道AImpl的大小?

c++ pimpl-idiom c++11

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

std :: list <std :: unique_ptr>:空的初始化列表与默认构造函数

代码

#include <list>
#include <memory>

class B;
class A {
    std::list<std::unique_ptr<B>> bs;
public:
    A();
    ~A();
};

int main()
{
    A x;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

显然编译.它没有链接因为A::A()并且A::~A()缺失,但这是预期的并且没有问题.更改

std::list<std::unique_ptr<B>> bs;
Run Code Online (Sandbox Code Playgroud)

应该称之为std::list标准构造函数

list() : list(Allocator()) {}
Run Code Online (Sandbox Code Playgroud)

(C++ 14及以上)来

std::list<std::unique_ptr<B>> bs{};
Run Code Online (Sandbox Code Playgroud)

应该调用list(std :: initializer_list,const Allocator&= Allocator()); 默认构造函数也是.(感谢Nicol Bolas,他正确地提到[over.match.list] 13.3.1.7)在c ++(Ubuntu 5.2.1-22ubuntu2)5.2.1 20151010--std = c ++ 17参数中给出以下错误:

/usr/include/c++/5/bits/unique_ptr.h: In instantiation of ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = B]’:
/usr/include/c++/5/bits/unique_ptr.h:236:17:   required from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() …
Run Code Online (Sandbox Code Playgroud)

c++ unique-ptr c++17

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

Pimpl with unique_ptr:为什么我必须将接口构造函数的定义移动到".cpp"?

只要我不将构造函数(of B)的定义移动到头部,代码就会工作B.h.

BH

class Imp;  //<--- error here
class B{
    public:
    std::unique_ptr<Imp> imp;
    B();     //<--- move definition to here will compile error
    ~B();
    //// .... other functions ....
};
Run Code Online (Sandbox Code Playgroud)

B.cpp

#include "B.h"
#include "Imp.h"
B::B(){ }
~B::B(){ }
Run Code Online (Sandbox Code Playgroud)

Imp.h

class Imp{};
Run Code Online (Sandbox Code Playgroud)

Main.cpp (编译我)

#include "B.h"
Run Code Online (Sandbox Code Playgroud)

错误:删除指向不完整类型的指针
错误:使用未定义类型'Imp'C2027

我可以以某种方式理解析构函数必须被移动到.cpp,因为Imp可能会被称为析构: -

delete pointer-of-Imp;  //something like this
Run Code Online (Sandbox Code Playgroud)

但是,我不明白为什么规则也涵盖了构造函数(问题).

我读过了 :-

c++ pimpl-idiom unique-ptr

6
推荐指数
1
解决办法
663
查看次数

std::unique_ptr&lt;T&gt; 不完整类型错误

我有

template<typename T>
class queue
{
private:
    struct node
    {
        T data;
        std::unique_ptr<node> next; //compile error on incomplete type

        node(T&& data_):
            data(std::move(data_))
        {}
    };

    std::unique_ptr<node> head;
    node* tail;

public:
        queue():
            tail(nullptr)
        {}
Run Code Online (Sandbox Code Playgroud)

我在 VS10 的标记行上收到编译错误。在这种情况下,我不应该被允许使用不完整的类型(实例化模板 - 构造函数 - 这里以 int 为例)?有解决办法吗?

编辑

singlethreadedqueue.h(62): error C2079: 'queue<T>::node::next' uses undefined class 'std::unique_ptr<_Ty>'
1>          with
1>          [
1>              T=MyClass
1>          ]
1>          and
1>          [
1>              _Ty=queue<MyClass>::node
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\memory(2161) : see reference to class template instantiation 'queue<T>::node' …
Run Code Online (Sandbox Code Playgroud)

c++ templates visual-studio-2010 unique-ptr c++11

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

不同的C++类声明

我正在尝试使用不使用命名空间的第三方C++库,并导致符号冲突.冲突的符号用于我的代码没有使用的类,所以我考虑为第三方库创建自定义头文件,其中类声明仅包括我的代码使用的公共成员,而忽略使用冲突类的任何成员.基本上创建一个界面.

我有三个问题:

  1. 如果.obj文件的编译工作,当我进行链接时,这种技术是否会导致符号冲突?

  2. 如果这不是问题,那么变化的类声明会在链接时引起问题吗?例如,链接器是否验证每个.obj文件使用的类的声明是否具有相同数量的成员?

  3. 如果这些都不是问题而且我能够链接.obj文件,它会在调用方法时引起问题吗?我不确切知道C++是如何工作的,但如果它使用索引指向类方法,并且那些索引从一个.obj文件到另一个不同,我猜这种方法会在运行时爆炸.

c++ compilation class declaration static-linking

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

包含一个以 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
查看次数

C++编译器是否有效隐式实例化模板类的所有成员函数?

假设我有一个公共类和一个私有实现类(例如PIMPL模式),我希望用一个带有checked delete的模板智能指针类来包装私有类,如下所示:

PublicClass.h

class PrivateClass;

// simple smart pointer with checked delete
template<class X> class demo_ptr
{
public:
    demo_ptr (X* p) : the_p(p) { }
    ~demo_ptr () {
        // from boost::checked_delete: don't allow compilation of incomplete type
        typedef char type_must_be_complete[ sizeof(X)? 1: -1 ];
        (void) sizeof(type_must_be_complete);
        delete the_p;
    }
private:
    X* the_p;
};

// public-facing class that wishes to wrap some private implementation guts
class PublicClass
{
public:
    PublicClass();
    ~PublicClass();

private:
    demo_ptr<PrivateClass> pvt;
};
Run Code Online (Sandbox Code Playgroud)

PublicClass.cpp

#include "PublicClass.h"

class PrivateClass
{ …
Run Code Online (Sandbox Code Playgroud)

c++ windows c++builder c++11

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

使用std :: unique_ptr的C++ Pimpl Idiom Incomplete Type

我为证明问题所需的大量代码道歉.我在使用带有std :: unique_ptr的pimpl习惯用法时遇到了问题.具体地说,当一个类(具有pimpl'ed实现)被用作具有pimpl'ed实现的另一个复合类中的成员数据时,似乎会出现问题.

我能够找到的大部分答案都是缺少明确的析构函数声明,但正如你在这里看到的,我已经声明并定义了析构函数.

这段代码有什么问题,可以修改它来编译而不改变设计吗?

注意:错误似乎发生在SomeComposite :: getValue()的定义中,并且编译器在编译时才能看到错误.在memory.h中遇到错误,消息是'sizeof'的无效应用程序到不完整类型'pimplproblem :: SomeInt :: impl'.

SomeInt.h

#pragma once
#include <iostream>
#include <memory>

namespace pimplproblem
{
    class SomeInt
    {

    public:
        explicit SomeInt( int value );
        SomeInt( const SomeInt& other ); // copy
        SomeInt( SomeInt&& other ) = default; // move
        virtual ~SomeInt();
        SomeInt& operator=( const SomeInt& other ); // assign
        SomeInt& operator=( SomeInt&& other ) = default; // move assign
        int getValue() const;

    private:
        class impl;
        std::unique_ptr<impl> myImpl;
    };
} …
Run Code Online (Sandbox Code Playgroud)

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

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

unique_ptr pimpl和不完整的类型

这不是std :: unique_ptr的欺骗,不完整的类型将无法编译.

请考虑以下代码:

#include <memory>

struct X
{
    X();
    ~X();    

    struct Impl; 
    std::unique_ptr<Impl> up_;
};

struct Impl {}; // fully visible here

X::X() : up_{nullptr}{}
X::~X() = default;

int main()
{
    X x;
}
Run Code Online (Sandbox Code Playgroud)

Live on Coliru

gcc/clang都吐出错误说不Impl完整.但是,我提供了一个默认的析构函数,X 后面 Impl是完全可见的,所以IMO代码应该编译.为什么不呢?现在出人意料:如果我做Impl了一个内部类,即定义

struct X::Impl{};
Run Code Online (Sandbox Code Playgroud)

相反,即使没有提供析构函数,代码也会编译.为什么会这样?我们不应该提供这样的默认析构函数,至少根据第一行中提到的链接?

c++ pimpl-idiom c++11

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

类内将不完整类型的 unique_ptr 初始化为 nullptr 时,gcc 编译错误

我正在使用 pimpl idiom 和 unique_ptr 编写一些代码。当我尝试使用类内初始化将 unique_ptr 默认设置为 nullptr 时,gcc 给出了编译错误,而 clang 和 msvc 都成功编译了代码。如果我没有使用类内初始化,错误就会消失。

\n\n
// A.h\n#pragma once\n\n#include <memory>\n\nusing namespace std;\n\nclass B;\nclass A\n{\nprivate:\n    ////////////////////////\n    // here gives the error!\n    ////////////////////////\n    unique_ptr<B> impl{nullptr}; // error only with gcc, \n                                 // ok with clang and msvc\n    unique_ptr<B> impl2; // ok with all three\n\npublic:\n    A();\n    ~A();\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n
// A.cpp\n#include "A.h"\n\nclass B\n{\nprivate:\n    int b{5};\n\npublic:\n    B() = default;\n    ~B() = default;\n};\n\nA::A() = default;\nA::~A() = default;\n
Run Code Online (Sandbox Code Playgroud)\n\n
// main.cpp\n#include "A.h"\n\nint main()\n{\n    A a;\n    return 0;\n}\n …
Run Code Online (Sandbox Code Playgroud)

c++ pimpl-idiom unique-ptr in-class-initialization gcc8

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