0

私のC ++の知識は最小限です。このため、私はこれを求めています:

タイプのオブジェクトへのポインターがあり、Ndbこれを行います:

Ndb* myObj=new Ndb();
NdbError err=myObj->getNdbError();
//Do some work;
//Finish the job
delete(myObj);

メソッドのシグネチャgetNdbErrorは次のとおりです。

const NdbError& getNdbError() const

署名によると、誰がメモリを解放する必要がありNdbErrorますか? const前は、NdbError&結果しか読めず、他に何もすべきではないことを意味しますか? 割り当てられているが参照されていないメモリ領域を残したくありません。

編集: ansersによると、このユースケースをもっと見せたほうがいいです。C++ オブジェクトと C メソッドの間にラッパーがあります。

void* WINAPI new_Ndb(void* cluster_connection,const char* catalogname,const char* schemaName)
{

    Ndb_cluster_connection* co=(Ndb_cluster_connection*)cluster_connection;
    Ndb* tmpN=new Ndb(co,catalogname,schemaName);
    return (void*)tmpN;
}

void WINAPI Ndb_dispose(void* obj)
{
    delete (Ndb*)obj;
    obj=0;
}

const ndberror_struct WINAPI Ndb_getNdbError(void* obj)
{
    Ndb* tmp=(Ndb*)obj;

    NdbError res=tmp->getNdbError();    
    ndberror_struct tmpRes;
    tmpRes=(ndberror_struct)res;
    return tmpRes;
}

NdbError は演算子のオーバーロードを定義します:

  operator ndberror_struct() const {
    ndberror_struct ndberror;
    ndberror.status = (ndberror_status_enum) status;
    ndberror.classification = (ndberror_classification_enum) classification;
    ndberror.code = code;
    ndberror.mysql_code = mysql_code;
    ndberror.message = message;
    ndberror.details = details;
    return ndberror;
  }

に電話をかけると何が表示されますか

const ndberror_struct WINAPI Ndb_getNdbError(void* obj)?

Ndberror は範囲外になりますが、コピーされるためデータを保持しますか? 戻り値 ndb_error_struct が範囲外になると、それらは解放されますmessagedetails?char*

4

4 に答える 4

2

ほとんどの場合、データ メンバーへの参照を返しますが、その必要はありませんdelete

errからの戻り値のコピーになりますがgetNdbError、これはスタック変数であるため、スコープの最後で破棄されます。心配する必要はありません。

于 2013-11-08T14:28:48.323 に答える
1

この関数const NdbError& getNdbError() const;は、への定数参照を返しますNdbError

コピーNdbError errは関数の終了時に自動的に削除されます。

ただし、コピーを作成するのではなく、常に参照する必要があります。つまり、次のように変更します。

 NdbError err=myObj->getNdbError();

 const NdbError& err=myObj->getNdbError();

myObjのメモリを処理することは明らかですNdbError

于 2013-11-08T14:36:35.663 に答える
1

getNdbError()、オブジェクトへの const 参照を返しNdbErrorます。あなたはdelete参照していません。あなたはあなたが編集したdeleteものだけです。new

動的な有効期間とは対照的に、自動有効期間getNdbErrorを持つオブジェクトへの戻り値を割り当てます。NdbError

NdbError err=myObj->getNdbError();

errここに自動変数があります。「範囲外」になると自動的に破棄されます。

提供したコードがプロジェクトにあるものと同じである場合、後で破棄されることに注意してくださいerrこれは適切です。と の間にリンクがあり、のデストラクタに未定義の動作やその他の悪いものが存在しないために発生する場合は、設計を再検討する必要があります。 myObjdeleteerrmyObjerrmyObj

動的割り当てをまったく使用しないか、少なくともスマート ポインターのような RAII コンストラクトでラップする必要がある場合は、割り当てと割り当て解除をより構造化された方法で処理できるようにすることを強くお勧めします。

于 2013-11-08T14:33:24.183 に答える
1

この関数は、によって管理されるオブジェクトへの参照を返しますmyObj。おそらくそのメンバーの1人です。そのオブジェクトを解放するために何もする必要はありません。myObj壊れた時は注意が必要です。

返された参照を使用して、自動変数errを初期化してそのコピーにしています。すべての自動変数と同様に、スコープ外になると自動的に破棄されます。そのオブジェクトを解放するために何もする必要もありません。

myObjただし、動的割り当てを行う正当な理由がない限り、おそらく自動変数も作成する必要があります。newと の間で何らかの例外がスローされると、コードでメモリ リークが発生しdeleteます。

于 2013-11-08T14:30:35.933 に答える