0

あなたのために何かを作る多くのC++API(COMベースのものが頭に浮かぶ)では、構築されるオブジェクトへのポインターは通常ポインターとして必要です**(そして関数はあなたのためにそれを構築して初期化します)

通常、次のような署名が表示されます。

HRESULT createAnObject( int howbig, Object **objectYouWantMeToInitialize ) ;

--しかし、新しいオブジェクトが戻り値として渡されることはめったにありません。

エラーコードを見たい人以外に、その理由は何ですか?**次のような単純な操作には、返されるポインタではなく、パターンを使用する方がよいでしょうか。

wchar_t* getUnicode( const char* src ) ;

または、これは次のように記述したほうがよいでしょうか。

void getUnicode( const char* src, wchar_t** dst ) ;

私が考えることができる最も重要なことはそれを解放することを忘れないことです、そしてその**方法は、何らかの理由で、私もそれを割り当て解除しなければならないことを私に思い出させる傾向があります。

4

7 に答える 7

11

「エラーコードが欲しいだけでなく」?

何があなたに他にもあると思わせるか。エラーコードが唯一の理由です。この関数には、失敗を示す何らかの方法が必要です。Cには例外がないため、ポインターパラメーターまたは戻り値のいずれかを使用してこれを行う必要があります。戻り値は慣用的であり、関数を呼び出すときに簡単に確認できます。

(ちなみに、**オブジェクトを解放する必要があるという普遍的なルールはありません。常にそうであるとは限りません。任意のオブジェクトを使用して、クリーンアップするオブジェクトを思い出させるのはおそらく悪い考えです。)

于 2010-06-08T22:33:31.443 に答える
2

2つの理由が思い浮かびます。

最初は実際のエラーコードです。C ++を除いて、Cには例外がなく、COMはC-APIです。また、多くのC ++ベースのプロジェクトは、さまざまな理由で例外を使用しないことを好みます。戻り値がエラーを通知できない場合があります。たとえば、関数が整数を返す場合、エラーコードを表す整数値がない場合があります。ポインターを使用してエラーを通知するのは簡単ですが(NULL ==エラー)、一部のAPI設計者は、すべての関数に対して一貫した方法でエラーを通知することを好みます。

次に、関数は1つの戻り値しか持てませんが、関数を呼び出すと複数のオブジェクトが作成される可能性があります。一部のWin32API関数は、NULL以外のポインタを使用してこれらの関数を呼び出す場合、オプションで入力できるポインタへの複数のポインタを取ります。戻り値が複数のポインターを含む値による構造体である場合、2つのポインターを返すことはできません。あるいは、これを使用するのは厄介です。ここでも、一貫性のあるAPIを達成することが賢明な目標です。

于 2010-06-08T22:41:38.440 に答える
1

渡される関数の引数の新しいオブジェクトの**方が優れています。これにより、たとえば関数の成功や関数を提供する他の情報を返すための変更を将来使用することができvoidます。bool

1行で答えてください:これは、結果として生じるエラーコードに対してはるかに優れています

于 2010-06-08T22:35:42.580 に答える
1

エラーコードを見たい人以外に、その理由は何ですか?

これにはいくつかの理由があります。それらの1つは、Cで使用できるインターフェイスを作成することです(これは、WinAPIおよびWindows COMで確認できます)。

下位互換性も別の理由です(つまり、インターフェイスはそのように記述されていて、今それを壊すと既存のコードが壊れます)。

このようなコードを使用する場合、設計原則としてC互換性を使用します。C ++で書くとしたら、

retval Myfunction(Result *& output);

それ以外の

retval Myfunction(Result ** output);

または(さらに良い):

Result *Myfunction();

そして、関数にエラー時に例外をスローさせます。

于 2010-06-09T08:54:18.020 に答える
0

それが最善の方法であることに同意するかどうかはわかりません...これはより良いかもしれません:

Object * createAnObject(int howbig, HRESULT * optPlaceResultCodeHereIfNotNull = NULL);

そうすれば、二重間接参照(慣れていない人にとっては少し注意が必要です)をいじることがなく、結果コードを気にしない人は2番目のコードを気にする必要がありません。引数はまったくありません...戻り値がNULLかどうかを確認するだけです。

実際、C ++なので、関数のオーバーロードを使用すると、さらに簡単になります。

Object * createAnObject(int howbig);
Object * createAnObject(int howbig, HRESULT & returnResultCode);
于 2010-06-08T22:38:53.200 に答える
0

COM呼び出しのメソッド呼び出しはすべてHRESULTである必要があります。戻りコードはフレームワーク全体で活用され、ダブルポインターを渡すことは、作成されたオブジェクトを取得するためのよく知られた方法です。

于 2010-06-08T22:41:08.037 に答える
0

あなたの質問には答えませんが、あなたの質問としてのコメントは、C++を使用したCOM/DCOMプログラミングについて私が持っているいくつかの考えを引き出しました。

これらすべての「ポインタ」と「ポインタからポインタ」、メモリ管理、および参照カウントが、C++でCOMプログラミングを行うことを躊躇する理由です。ATLを設置しても、自然に見えないという単純な理由で嫌いです。そうは言っても、私はATLを使用していくつかのプロジェクトを行いました。

当時の代替手段はVBを使用することです。VBコードは、COMまたはDCOMプログラミングではより自然に見えます。

今日はC#を使用します。

于 2010-06-08T22:55:54.343 に答える