私は学習目的でC言語で汎用スタックを実装しています。これは、それのポップ機能である:関数のトップスタック実装C
void* StackPop(Stack *s) {
assert(s != NULL);
assert(s->logicalLen > 0); // there must be at least on element
void *object = (char*) s->elems + (s->logicalLen--) * s->elemSize; // decrement logical length
// on the fly
return object;
}
この場合(StackPopは)私が呼び出し元に一番上にオブジェクトの所有権を移転しなければならないことを私には明らかです。したがって、呼び出し元がオブジェクトを使って何をすべきかを決めるため、汎用ポインタを返すのは問題ありません。 一方、先頭の要素を返すStackTop()関数を記述したいと思います。ここで私は不安を抱いています。私は、両方の関数が、クライアントの変更を望まないので、スタックのサイズを減らしたり、ポインタを返さないようにしてください。どのように上位要素のコピーのみを渡すのですか?引数としてジェネリックポインタを唯一のオプションとして受け取り、そのアドレスに深いコピーを作成しますか?
void StackPop(void *target) {
// make a deep copy into target address with memcopy or whatever?
}
もっと良いアプローチがありますか?
無関係に、私は 'StackPop'を書いて、健全性と他のすべての体操の前に空のスタックをチェックしてみましょう。そして、言語を選んでください:適合と形はCを示唆します。 C++ではありません。 – WhozCraig
@WhozCraig真実、私はそれをすぐに書きました。私は現時点でエラーチェックに多くの注意を払っていません。私はそれを修正します。 – blade
あなたの問題を解決するための「適切な」方法は、ポップ関数が*何かを返さないようにすることです(エラー状態を除いて)。トップファンクションを介して "トップ"オブジェクト(ある場合)へのアクセスのみを許可します。呼び出し元がオブジェクトのコピーを望むなら、それもそうです。彼らはポップ前に1つを作ることができます。これは、偶然にもC++の標準ライブラリコンテナアダプタ 'std :: stack'の動作とは異なります。そして、btw、 'assert'はリリースコードではオペレーションにはならないので、あなたが気づいていない場合に備えて、論理エラーチェックが必要です。 –
WhozCraig