-1

我有一个返回Customer对象(不是指针)的函数,如下所示:

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

此函数从 a (它是一个链表)获取一个Customer对象。CustomerList

我正在尝试Customer使用以下函数操作列表中的 (此函数将一个添加AccountCustomer对象中。)

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

但是,在此函数调用之后,Customer对象 inCustomerList不会改变。我认为原因是我返回了一个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;

如果索引超出范围,这将返回一个空指针。如果这是您想要的行为,那么您需要在取消引用指针之前进行检查:

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

而且,出于礼貌,您应该返回一些看起来更像空指针的东西,例如nullptr,NULL0

抛出异常可能是一个更好的主意(也许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不是通过引用重新调整的,因此 List 中的原始对象不会被修改。

  1. 在我更改我的函数和函数调用后,为什么它会给我上面提到的错误?

我认为您需要共享addAccount方法的代码。问题可能在里面。考虑到原始代码return by value,它可以正常工作(无一例外)。

于 2013-05-07T15:12:20.917 回答