相关疑难解决方法(0)

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
查看次数

当没有创建类的实例时,该标准是否允许不隐式定义隐式虚拟析构函数?

在思考这个问题时,我偶然发现了我不了解的其他内容。

标准说...

[class.dtor] / 4

如果类没有用户声明的析构函数,则将析构函数隐式声明为默认值。隐式声明的析构函数是其类的内联公共成员。

[class.dtor] / 10

[...]如果类具有带有虚拟析构函数的基类,则其析构函数(无论是用户声明的还是隐式声明的)都是虚拟的。

[class.dtor] / 7

默认使用但未定义为deleted的析构函数在使用odr时或在其首次声明后被明确默认为隐式定义。

[basic.def.odr] / 3

[...]如果虚拟成员函数不是纯函数,则将被使用。[...]

所以现在我想知道这段代码是否应该编译:

#include <memory>

struct Base {
    virtual ~Base() = default;
};

struct Bar;
struct Foo : Base {
    std::unique_ptr<Bar> bar_{};
};
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/B0wvzd

我认为~Foo()必须对其进行隐式定义,因为它是虚拟的,但由于Bar在此TU中不完整,因此无法编译。但是代码可以在所有主要的编译器中编译。

我想念什么?

c++ one-definition-rule language-lawyer implicit-declaration virtual-destructor

7
推荐指数
1
解决办法
188
查看次数