C++:auto_ptr + 前向声明?
-
21-09-2019 - |
题
我有一堂这样的课:
class Inner;
class Cont
{
public:
Cont();
virtual ~Cont();
private:
Inner* m_inner;
};
在 .cpp 中,构造函数创建一个实例 Inner
和 new
和析构函数 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。在我的情况下解决了这个问题。
您是不是技术上应该实例化标准库模板使用不完全类型,虽然我知道没有实现,其中这是行不通的。在实践中,锐齿的答案是什么,我会推荐。
有真的没有什么毛病使用裸指针的指针参数impl,只要您拨打您的析构函数就可以删除。你应该还实现或禁用拷贝构造函数和赋值运算符。