0

私はこれらの質問についてしばらくの間潜んでいて、多くのことを学びましたが、最近、理解できない問題に直面しました. 私は Qt を使用しており、さまざまなクラス メソッド (最終的には QLabel に設定されます) で QMovie オブジェクトを作成/置換する必要があります。new キーワードを使用してオブジェクトを定義しました。したがって、私が持っているヘッダーに

QMovie * movie;

簡単にするために、同等のコードを 1 つのメソッドにまとめます。これは、2 行のコードに相当します。

QMovie * movie = new QMovie(QByteArray1,this);
QMovie * movie = new QMovie(QByteArray2,this);

これは機能しますが(理由はわかりません)、繰り返しの操作であるため、メモリリークが心配です。2 番目の定義が最初の定義を正常に置き換えているように見えますが、おそらくそれぞれに異なるポインターがあるため、最初の定義へのポインターを削除する方法がわかりません。クラス デストラクタでムービーを削除しましたが、すべてが削除されるかどうかわかりません。ここで何が起こっているか知っている人はいますか?

PS QByteArray (Web からダウンロードした) のデータを使用して QMovie オブジェクトを作成する唯一の方法 (Qt で見つけた) は、QMovie コンストラクターを使用することであるため、これを行います。現在のムービー データをファイルの新しいデータに置き換えたいだけの場合は、次のメソッドを使用できます。

movie->setFileName(fileName);

ただし、バイナリ データを使用する場合、これはオプションではありません。注: QMovie には、引数として QByteArray の代わりにファイル名を持つコンストラクターもあります。ファイル名を使用すると、上記のコードを使用しても機能し、テストが容易になります。

どんな助けでも大歓迎です。

4

3 に答える 3

2

一般に、 から派生したものが s のQObject階層に含まれているQObject場合、それらは親が破棄されると自動的に破棄されます。あなたの場合、QMovieコンストラクターを介して親を指定しているため、クリーンアップを処理する必要があります。確認したい場合は、QMovie からクラスを派生させ、メッセージを出力するデストラクタを実装し、予期したときに呼び出されるようにします (つまり、親が破棄されたとき)。

于 2012-06-13T01:29:52.973 に答える
1

Cでそれを行う慣用的な方法は次のとおりです。

  1. ポインターをゼロに初期化します。

  2. 代入する前free()は、古いポインターが指すオブジェクト。ゼロをチェックする必要はありませんfree()ゼロ ポインターでは安全なノーオペレーションです。

  3. free()ポインターがスコープ外に出たときのオブジェクト。

Qt での慣用的な方法はさらに簡単です。

  1. QSharedPointer<>またはを使用しQScopedPointer<>ます。範囲外になると、ポイント先のオブジェクトが自動的に削除されます。

    • オブジェクトを所有するポインターが 1 つだけの場合は、 を使用しますQScopedPointer。スコープ外になると、ポイント先のオブジェクトが削除されます。これは に似ていstd::auto_ptrます。

    • 所有権を共有するには、 を使用しますQSharedPointerQSharedPointerそれを指す最後のオブジェクトがスコープ外になる/破棄されると、ポイントされたオブジェクトが削除されます。

  2. の場合、メソッドをQScopedPointer使用reset(T*other)してポインタに新しい値を割り当てます。の場合QSharedPointer、次のような他の共有ポインタのみを割り当てることができますQSharedPointer a = QSharedPointer(new Class);

いずれの場合も、以前に指定されたオブジェクトは削除されます。

したがって:

class MyClass {
  QScopedPointer<QMovie> movie1;
  QSharedPointer<QMovie> movie2;
public:
  MyClass {} // note: no need for any special initialization
  void method() {
    movie1.reset(new QMovie(...));
    movie2 = QSharedPointer(new QMovie(...));
  }
};

これは完全に安全です。MyClass::method()メモリリークなしで、何度でも呼び出すことができます。任意の時点で、MyClass は最大 2 つの QMovie オブジェクトを維持します。

于 2012-06-13T02:53:39.040 に答える
0
QMovie * movie = new QMovie(QByteArray1,this);
QMovie * movie = new QMovie(QByteArray2,this);

これらの 2 行が同じ.ccファイルにある場合、再定義エラーが発生します。2 つの行が別々.ccのファイルにある場合、実行可能ファイルをビルドすると、複数定義エラーが発生します。しかし、あなたの質問には次の文言があります。

Qt を使用しており、さまざまなクラス メソッドで QMovie オブジェクトを作成/置換する必要があります (最終的には QLabel に設定されます)。

オブジェクトが異なるクラスに存在する場合、QMovie各クラスのポインターは別のポインターとは異なるため、メモリ リークは発生しません。

ただし、すべてのクラスが同じインスタンスを参照することを意図しているQMovie場合は、インスタンスを各オブジェクトに渡す方法を見つける必要があります。または、それらすべてが同じものを参照するようにします (つまり、シングルトン パターンを使用します)。

于 2012-06-13T01:29:23.090 に答える