繁体   English   中英

C ++:auto_ptr +转发声明?

[英]C++: auto_ptr + forward declaration?

我有一个这样的课:

class Inner;

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

在.cpp中,构造函数使用new创建Inner实例,并使用析构函数delete s it。 这工作得很好。
现在我想更改此代码以使用auto_ptr所以我写道:

class Inner;

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

现在,构造函数初始化了auto_ptr ,而析构函数什么都不做。

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

警告C4150:删除指向不完整类型'Inner'的指针; 没有破坏者叫

那么,这显然是很糟糕,我明白为什么会发生,编译器不知道的德托尔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中,在Inner一切都没关系之后就好了。

这似乎很荒谬,但我通过在Cont.h文件中添加#include <memory>解决了同样的问题。

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

boost::shared_ptr<class NeverHeardNameBefore> ptr;

没关系,没有额外的声明。

shared_ptr不仅仅是auto_ptr,比如引用计数,但如果你不需要它,它不应该受到伤害。

如果你在cont.cpp文件中实现析构函数并且你包含inner.h,那么标题中的forward声明是可以的,正如其他人指出的那样。

问题可能在于Cont的使用。 在每个使用(和销毁)Cont的cpp中,你必须包含cont.h和inner.h。 这解决了我的问题。

这个问题 (删除带有私有析构函数的对象)和这个问题 (如何编写iscomplete模板)可能对你有帮助。

从技术上讲,您不应该使用不完整的类型来实例化标准库模板,尽管我知道没有实现它不起作用。 在实践中,Sharptooth的答案也是我推荐的。

对于你的impl指针使用裸指针确实没有任何问题,只要你在析构函数中调用delete就可以了。 您可能还应该实现或禁用复制构造函数和赋值运算符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM