我有一堂这样的课:

class Inner;

class Cont
{
public:
    Cont();
    virtual ~Cont();
private:
    Inner* m_inner;
};

在 .cpp 中,构造函数创建一个实例 Innernew 和析构函数 delete是的。这工作得很好。
现在我想更改此代码以使用 auto_ptr 所以我写:

class Inner;

class Cont
{
public:
    Cont();
    virtual ~Cont();
private:
    std::auto_ptr<Inner> m_inner;
};

现在,构造函数初始化了 auto_ptr 并且析构函数什么也不做。

但这不起作用。当我实例化这个类时,问题似乎出现了。我收到这个警告:

警告 C4150:将指针删除为不完整的类型“内部”;没有攻击者

好吧,这显然非常糟糕,我明白为什么会发生这种情况,编译器不知道 Inner 当实例化模板时 auto_ptr<Inner>

所以我的问题是:有没有办法使用 auto_ptr 像我在仅使用普通指针的版本中那样使用前向声明?
不得不 #include 我声明指向的每个类都是一个巨大的麻烦,有时甚至是不可能的。这个问题通常是如何处理的?

有帮助吗?

解决方案

您需要包括限定class Inner入其中Cont::~Cont()执行所在的文件头中。这样,你仍然有在格兰板分隔class Cont一个向前声明和编译器看到class Inner定义,并可以调用析构函数。

//Cont.h
class Inner; // is defined in Inner.h
class Cont 
{ 
    virtual ~Cont(); 
    std::auto_ptr<Inner> m_inner;
};

// Cont.cpp
#include <Cont.h>
#include <Inner.h>

Cont::~Cont()
{
}

其他提示

原来只有当我使c'tor直列出现问题。如果我把c'tor的CPP,的decleration后Inner一切正常。

您可以考虑的boost :: shared_ptr的()代替。它没有实际的缺点,而不是性能,并且更加友好的转发声明:

boost::shared_ptr<class NeverHeardNameBefore> ptr;

是好的,没有上述额外声明。

shared_ptr的确实比auto_ptr的,如引用计数多,但如果你不需要它,它不应该伤害。

这似乎是荒谬的,但我加入#include <memory>到Cont.h文件解决了同样的问题。

在头向前声明如果实现在cont.cpp文件中的析构函数,你包括inner.h,正如其他人指出是确定的。

在问题可能是在使用续的。在使用(和破坏)每个CPP续您必须包括cont.h和inner.h。在我的情况下解决了这个问题。

这个问题 (使用私有析构函数删除对象)和 这个问题 (如何编写 iscomplete 模板)可能会对您有所帮助。

您是不是技术上应该实例化标准库模板使用不完全类型,虽然我知道没有实现,其中这是行不通的。在实践中,锐齿的答案是什么,我会推荐。

有真的没有什么毛病使用裸指针的指针参数impl,只要您拨打您的析构函数就可以删除。你应该还实现或禁用拷贝构造函数和赋值运算符。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top