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()
を定義するヘッダーを含める必要があります。それでもtehのヘッダ定義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インラインを作るときにのみ問題が発生判明します。私はInner
のすべてのOKのdecleration後、CPPにc'torを置く場合ます。
あなたは代わりに)(ブースト:: shared_ptrのを考慮することができます。それは代わりに、パフォーマンスの実用的な欠点を持っていない、とはるかに友好宣言を転送することです。
boost::shared_ptr<class NeverHeardNameBefore> ptr;
上に余分な宣言せずに、大丈夫です。
shared_ptrのように参照カウントとして、より多くのauto_ptrよりもありませんが、あなたがそれを必要としない場合、それは傷つけるべきではありません。
ばかげているようだが、私はCont.hファイルに#include <memory>
を追加することによって、同じ問題を解決しました。
ヘッダー内の前方宣言はokですし、他の人が指摘したようにあなたは、inner.h含まれます。
問題は続きの使用である可能性があります。用途(および破棄)続き、各CPPでは、cont.hとinner.hを含める必要があります。それは私の場合には問題を解決します。
はあなたが技術的には、不完全なタイプで、標準ライブラリテンプレートをインスタンス化することになっていません。実際には、Sharptoothの答えは私もお勧めしたいものです。
本当に長いあなたのデストラクタでそれを削除呼び出すようとして、あなたのimplポインタのための裸のポインタを使用して何も間違ってはありませんでした。おそらく、また、コピーコンストラクタと代入演算子を実装するか、無効にする必要があります。