質問

次のようなクラスがあります。

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()を定義するヘッダーを含める必要があります。それでも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>を追加することによって、同じ問題を解決しました。

あなたはcont.cppファイルでデストラクタを実装する場合は、ヘッダー内の前方宣言はokですし、他の人が指摘したようにあなたは、inner.h含まれます。

問題は続きの使用である可能性があります。用途(および破棄)続き、各CPPでは、cont.hとinner.hを含める必要があります。それは私の場合には問題を解決します。

この質問 (プライベート デストラクターを使用したオブジェクトの削除) および この質問 (iscomplete テンプレートの書き方) が役立つかもしれません。

私はどここれは動作しませんなしの実装を知っているが、

はあなたが技術的には、不完全なタイプで、標準ライブラリテンプレートをインスタンス化することになっていません。実際には、Sharptoothの答えは私もお勧めしたいものです。

本当に長いあなたのデストラクタでそれを削除呼び出すようとして、あなたのimplポインタのための裸のポインタを使用して何も間違ってはありませんでした。おそらく、また、コピーコンストラクタと代入演算子を実装するか、無効にする必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top