当前位置: 首页 > 知识库问答 >
问题:

pimpl的Unique_ptr用法-即使声明了析构函数,也不会编译

荆弘伟
2023-03-14

Wrapper.h:

#pragma once
#include <memory>

struct Wrapper
{
    class Impl;
    ~Wrapper();
    std::unique_ptr<Impl> _impl;
};

wrapper.cpp:

#include "wrapper.h"

class Wrapper::Impl {};
Wrapper::~Wrapper() = default;

这个文件编译得很好。但是,在编译main.cpp时,我会得到不完整的类型错误(请参见下面的错误):

#include "wrapper.h"

int main()
{
    Wrapper w;
    return 0;
}
    null

根据@AdrianMole的建议,我在类包装器定义中添加了一个ctor声明,出于某种原因,它修复了错误,尽管错误(以及unique_ptr规范)引用了析构函数。

更新的wrapper.h:

struct Wrapper
{
    class Impl;
    Wrapper();
    ~Wrapper();
    std::unique_ptr<Impl> _impl;
};

所以我要加上一个问题:

    with

    [

        _Ty=Wrapper::Impl

    ]
    with

    [

        _Ty=Wrapper::Impl

    ]

内存(2574):消息:请参见对正在编译的类模板实例化'STD::Default_DeleteWrapper::Impl'的引用

wrapper.h(9):消息:请参见对正在编译的类模板实例化'std::unique_ptrwrapper::impl,std::default_delete '的引用

内存(2536,25):错误C2338:无法删除不完整的类型

共有1个答案

郑宇
2023-03-14

任何构造函数定义(包括隐式定义的默认构造函数)都可能调用类类型的所有成员对象的类型的析构函数。这样做的理由是,如果构造较晚的成员引发,则需要调用所有先前成员的析构函数。在最后一个成员的情况下,这并不是严格要求的,但标准没有作此例外。

例如,如果您的类是:

struct complete_type_with_throwing_constructor {
    complete_type_with_throwing_constructor() { throw 0; }
};

struct Wrapper
{
    class Impl;
    ~Wrapper();
    std::unique_ptr<Impl> _impl;
    complete_type_with_throwing_constructor x;
};

然后,Wrapper的隐式默认构造函数将构造_impl,然后在X的默认构造函数抛出后销毁它。

 类似资料:
  • 问题内容: 我想用主方法创建一个简单的Java类,但是在编译代码时,出现以下错误消息: 错误:在类error.TestErrors中找不到主方法,请将主方法定义为:public static void main(String [] args) 这是源代码: 为什么我看到此错误,如您所见,我已经声明了main方法! 问题答案: 正如我在评论中所说,您似乎已经在自己的类中声明了一个类。为了证明这一点,

  • 我正试图编写代码,从一个Android应用程序发送一条短信,但当我试图发送短信时,它给我返回了错误: 我检查了,但我拥有清单中的权限,如下所示: null null 我在网上搜索了一下,但是所有的错误都是关于语法的,你能帮我一下吗?

  • 我正在尝试声明和初始化一个保存类数组 这是我用来解决项目内存管理问题的示例。我可以声明指针,但无法初始化它。 收到的错误: 对非常量表达式函数“void*operator new”的调用std::unique_ptr ship_crew_members=std::make_unique

  • 我刚刚下载了谷歌新的android studio捆绑包(适用于Windows的x64),还安装了JDK8(C:\Program Files\Java\jdk1.8.025)(x64版本)。 但是在Android Studio设置中,它不会检测到JDK,并要求找到它的路径。我找到了它的路径,但它仍然说它是无效的。 我尝试声明新的环境变量(系统和用户),但我仍然得到同样的错误。 我也试过cmd上面说j

  • 我试图理解声明合并的行为。我创建了一个声明文件,它重新声明了模块的一个函数接口。npm模块“模式验证器”带有自己的类型。 我仅将此模块用作示例来演示行为。这个问题与schemavalidator模块无关。 我注意到,即使我没有导入声明文件,typescript仍然使用它。 我试图做的是,仅当我使用import语句导入自定义声明文件时才使用它。 这是我的2个文件 首先是我的自定义声明文件。在这里,我

  • 5.1. 函数声明 函数声明包括函数名、形式参数列表、返回值列表(可省略)以及函数体。 func name(parameter-list) (result-list) { body } 形式参数列表描述了函数的参数名以及参数类型。这些参数作为局部变量,其值由参数调用者提供。返回值列表描述了函数返回值的变量名以及类型。如果函数返回一个无名变量或者没有返回值,返回值列表的括号是可以省略的。如