2011-01-25 23 views
4

私は2つの4つのクラスがあります。ポインタの削除に関する質問。どのクラスを削除する必要がありますか?

  • MainClass(物事がスタートクラス)
  • たXmlReader(xmlファイルを解析するために使用されるクラス)
  • SerialPortSettingsは(シリアルに関する情報を保持していますxmlファイルから読み取られたポート、例えばボーレート、コンフォートなど)
  • SerialPortListener(シリアルポートそのコンストラクタでortSettingsオブジェクト)

MainClassは、XMLファイルから物事を読むための方法があります。 このメソッドでは、最初にのインスタンスを作成し、XmlReaderを作成し、コンストラクタパラメータとしてxmlファイルを与えます。このxmlReaderは、このメソッド内に存在する必要があります:

XmlReader xmlReader (xmlFile); 

xmlReaderはxmlFileを解析します。 MainClassは、get-methodsをXmlReaderで呼び出してxml-stuffにアクセスします。これまでのところすべてが良いです。

しかし、方法たXmlReaderオファーの一つは、XMLファイルから読み取られた情報に基づいてSerialPortSettingsのタイプのオブジェクトを作成する方法であって

SerialPortSettings* XmlReader::getSerialPortSettings() { 
    .... // reading stuff from xml file 
    return new SerialPortSettings(baudRate, dataBits, comport); 
} 

このメソッドが呼び出されますMainClassと戻り値がポインタに格納されています

SerialPortSettings* settings = xmlReader.getSerialPortSettings(); 

次のことMainCla SerialPortListener(MainClassが終了するまで存在しなければならないメンバ変数)を作成することです。 SerialPortListenerはそれのコンストラクタでSerialPortSettingsへの参照を取ります

m_serialPortListener = new SerialPortListener(*settings); 

が故にSerialPortSettingsもMainClassが終了するまで存在している必要があり、それゆえ私はポインタとしてこれを作成しました。だからここ

は手がかりである:私はSerialPortSettings -objectを削除しようとしましたSerialPortListenerデストラクタで

SerialPortListener::~SerialPortListener() { 
    delete &m_settings; 
} 

はその後MainClassデストラクタで、私はSerialPortListenerを削除しました-目的:

MainClass::~MainClass() { 
    delete m_serialPortListener; 
} 

これは失敗します。

*** glibc detected *** ./ioserver: double free or corruption (out): 0x00860d80 *** 

私はSerialPortListenerから削除& m_settingsを削除すると、それが正常に動作します:私は、私は、メインクラスで二回何かを削除したというエラーを取得します。 しかし、いつポインタを削除する必要がありますか?正しいことは何ですか?私は本当に私のXMLリーダーがSerialPortSettingsオブジェクトを作成し、すべての情報(ボーレート、comportなど)をMainClassに戻してSerialPortSettingsオブジェクト自体を作成するようにしたい。

答えて

0

MainClassの最後にポインタを削除してください。

0

deleteを参考にしても意味がありません(少なくとも私には)。

XMLリーダーが新しいオブジェクトを作成しないようにするには、それはクリーンです。 「ダム」容器としてSerialPortSettingsを治療、ちょうどXMLデータで埋めるための基準に合格:

XmlReader::getSerialPortSettings(SerialPortSettings& settings); 

実際のインスタンスは、メインプログラム内のローカル変数とすることができ、渡される(によってそれが作成のシリアルポートにconst参照、この時間):

SerialPortSettings portSettings; 
m_xmlReader->getSerialPortSettings(portSettings); 
m_serialPort = new SerialPort(portSettings); 

設定インスタンスのライフタイムは、当然、それはただのローカル変数なので、それは、中のスコープと同じです。

シリアルポートが有効範囲外になる前に、XMLを読み取るメインクラスのメソッドを終了する必要がある場合は、その設定をメインクラスのメンバ変数にすることができます。

+0

私はこのソリューションが好きです!ありがとう:) – Lisa

1

xmlReader::getSerialPortSettingsは、値でSerialPortSettingsを返すだけです。

コンパイラに最適化をさせます。

しかし、ここであなたは、このようなstd::auto_ptrboost::shared_ptrなどスマートポインタを、使用しない、ポインタの寿命を処理する必要があります。重要なアイデアは所有権を定義することです。所有者(boost::shared_ptrの場合、オブジェクトを参照するスマートポインタのコレクションです)は、–他の人を削除する責任があります。

乾杯& HTH。、

0

m_settingsのデータ型は何ですか?それはSerialPortSettings *かSerialPortSettingsですか?後者の場合は、スタックに割り当てられているので、そのように削除することはできません。前者(ポインタ)の場合は、参照演算子は必要ありません。任意のポインタについては

delete m_settings; 

はあなたが誰ownsポインタを決める必要があり、それは、それを削除人でなければなりません:

delete &m_settings; 

は次のようになります。単にあなたの削除にdelete m_settings;

+0

データ型og m_settingsはポインタ(アスタリスクなし)ではありません。私はserialportlistener.hでこのように定義しました:SerialPortSettings m_settings; – Lisa

+0

ちょうどこの行に気付きました:m_serialPortListener = new SerialPortListener(* settings); 設定を削除する必要があります。この行の後、SerialPortListener()でその内容をコピーしていると仮定します。 – badgerr

0

、単純なタイプミスを書きます。

shared_ptrなどのスマートポインタを使用して、問題を完全に排除できます。

0
SerialPortListener::~SerialPortListener() { 
    delete &m_settings; 
} 

このブロックはかなり変わっています。参照によって値を削除しようとしていませんか?原因C++は、クラスを削除すると自動的にそれを行います。したがって、削除は実際に2回削除しようとしています。

0

まず、SerialPortListener :: m_settingsがどのように格納されているのか、本当に重要な情報が欠落しています。エラーのあなたが取得しているので、私はあなたが実際に意味それのコピーを、保存している推測している:

class SerialPortListener { 
    SerialPortSettings m_settings; 

    SerialPortListener(SerialPortSettings set) { 
     m_settings = set; 
    } 
} 

それはこれに似た何かがいた場合、その後、私はあなたがこのような何かを持っている賭けますリスナーはオブジェクトのコピーを自身のメモリに保存していますが、削除するのはポインタではないので意味がありません。あなたがやっていることを知り、本当に必要であることを理解するまでは、決して削除しないでください。&

"正確さ"の観点からは、誰が作成したのかにかかわらず、メインクラスによってポインタを解放する必要があります。または、メインクラスでそれを使用していない場合に、リスナーに削除させたい場合は、リスナーにオブジェクトまたは参照の代わりにポインタを保存します。

+0

SerialPortListenerのコンストラクタには、SerialPortSettingsの参照パラメータがあります。SerialPortListener(SerialPortSettings&set){ m_settings = set; } – Lisa

+0

OK、重要なのは、とにかくm_settings宣言に関するビットです。 *私がやることは、ポインタを宣言して、どこで行ってもそれを削除することです – Lacrymology

0

m_serialPortSettingsをSerialPortListenerでポインタにしてそこから削除しました。

関連する問題