-1

Customer次のようなオブジェクト(ポインターではない)を返す関数があります。

Customer CustomerList::retrieve(const int index) const{
        if (index<1 || index>size)
                return false;
        else{
                Node *cur = find(index);
                return (cur->data);
        }
}

この関数は、(リンクされたリストである)Customerからオブジェクトを取得しますCustomerList

次の関数を使用してリスト内のを操作しようとしていCustomerます (この関数はオブジェクトに を追加します) AccountCustomer

list.retrieve(i).addAccount(acc);

ただし、この関数呼び出しの後、Customerオブジェクト inCustomerListは変更されません。その理由はCustomer、オブジェクト自体ではなく、オブジェクトのコピーを返すためだと思います。

したがって、Customer のアドレスを返して正しく操作するために、関数に次の変更を加えます。

Customer* CustomerList::retrieve(const int index) const{
        if (index<1 || index>size)
                return false;
        else{
                Node *cur = find(index);
                return &(cur->data);
        }
}

そして、次のように操作関数を呼び出します。

list.retrieve(i)->addAccount(acc);

しかし、「アクセス違反の読み取り場所0x00000044」が表示されます。エラー。私が学びたいのは:

  1. Customerそもそもオブジェクトを操作しないのはなぜですか? 私の仮定は正しいですか?
  2. 関数と関数呼び出しを変更した後、上記のエラーが表示されるのはなぜですか?
4

2 に答える 2

1

最初に Customer オブジェクトを操作しないのはなぜですか? 私の仮定は正しいですか?

あなたが言うように、あなたはコピーを返してそれを操作し、リストにあるものはそのままにしておきます。

関数と関数呼び出しを変更した後、上記のエラーが表示されるのはなぜですか?

ほぼ間違いなく、次の理由によります。

return false;

インデックスが範囲外の場合、null ポインターが返されます。それがあなたが望む動作である場合は、ポインターを逆参照する前に確認する必要があります。

if (Customer * c = list.retrieve(i)) {
    c->addAccount(acc);
} else {
    // handle the error?
}

nullptrまた、礼儀正しく、 、NULL、などの null ポインターに似たものを返す必要があります0

例外をスローすることをお勧めします (おそらくstd::range_error)。呼び出し元は、関数が返された場合にポインターが有効であると想定できます。その場合、元の例と非常によく似たコードを提供して、ポインターではなく参照を返す方がよい場合もあります。

Customer & CustomerList::retrieve(const int index) const{
    if (index<1 || index>size)
            throw std::range_error("Customer index out of range");
    else{
            Node *cur = find(index);
            return (cur->data);
    }
}

list.retrieve(i).addAccount(acc); // Does exactly what you'd expect

find適切と思われる場合は、範囲チェックを関数に移動することも検討してください。

于 2013-05-07T15:13:31.940 に答える
0
  1. 最初に Customer オブジェクトを操作しないのはなぜですか?

はい、あなたは正しいです。by valueデフォルトでは、参照ではなく返されるため、リスト内の元のオブジェクトは変更されません。

  1. 関数と関数呼び出しを変更した後、上記のエラーが表示されるのはなぜですか?

addAccountメソッドのコードを共有する必要があると思います。問題はその中にあるかもしれません。元のコードreturn by valueで考えると、(例外なく) 正しく動作していました。

于 2013-05-07T15:12:20.917 に答える