2014-12-06 56 views
10

说我有两类:的unique_ptr和前瞻性声明

“foo.h中”

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

    }; 

    ~Foo() 
    { 

    }; 
}; 

“A.H”

#pragma once 
#include <memory> 

class Foo; 

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

    std::unique_ptr<Foo> foo; 
}; 

A持有的Foo一个unique_ptr。我不想在“A.h”中包含Foo,所以我向前宣布了它。通过只向前声明类Foo在“啊”,我得到一个编译时错误:

error C2027: use of undefined type 'Foo' 
error C2338: can't delete an incomplete type 

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

“A.cpp”

#include "A.h" 

#include "Foo.h" 

A::A() 
{ 

} 

A::~A() 
{ 

} 

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

编辑: 我上传了4个文件,以便测试该程序。 我使用MSVC++的Visual Studio 2013年

http://www.filedropper.com/test_61

+5

'A'确实有一个构造函数,当你注释掉你constructo r:编译器提供了一个默认的构造函数,这个构造函数获得了一个内联定义。 – dyp 2014-12-06 21:32:46

+0

是的,但使用标准构造函数,我得到编译器错误,他无法删除完整类型。在编写我自己的空构造函数时,它应该看起来像默认的那样,我不会看到这些编译错误。 – abcheudg234 2014-12-06 21:40:29

+0

向我们展示不起作用的代码? – 2014-12-06 21:44:44

回答

-1

的是没有可能的 'A' 不具有构造函数。

如果您评论了您编写的构造函数,编译器将为您创建一个默认构造函数,它不一定与您定义的构造函数在同一个位置。造成了这个问题。

+1

但是为什么我必须在A.cpp中定义构造函数呢?我明白,编译器抱怨说,A的析构函数必须在Foo.h被包含的地方定义 - 这是一个完整的类型,A的析构函数实际上可以破坏Foo。但我不明白为什么A的CONstructor也必须在A.cpp中定义。您可以通过复制类并在main()中实例化A来尝试代码。当注释掉A的构造函数时,代码将不会编译。 – abcheudg234 2014-12-06 21:59:11

+3

你要起诉哪个编译器? – 2014-12-06 22:02:49

+1

我正在使用Visual Studio 2013的MSVC++编译器。 – abcheudg234 2014-12-06 22:06:41

14

的构造需要用同样的方法获得了缺失者的析构函数所做的:异常安全要求的构造能够回滚的情况下,所有的成员,你的构造函数的身体抛出的初始化:

[C++14: 12.6.2/10]: In a non-delegating constructor, the destructor for each potentially constructed subobject of class type is potentially invoked (12.4). [ Note: This provision ensures that destructors can be called for fully-constructed sub-objects in case an exception is thrown (15.2). —end note ]

相关: