我有一个返回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
(此函数会向Account
对象添加Customer
。)
list.retrieve(i).addAccount(acc);
但是,在此函数调用之后,Customer
中的CustomerList
对象不会更改。我假设原因是我返回了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。”错误。我想学的是:
Customer
对象?我的假设是对的吗?答案 0 :(得分:1)
为什么不首先操纵Customer对象?我的假设是对的吗?
正如你所说,你正在返回一份副本并对其进行操作,使列表中的副本保持不变。
在我更改函数和函数调用之后,为什么它会给我上面提到的错误?
几乎可以肯定是因为:
return false;
如果索引超出范围,那将返回空指针。如果这是您想要的行为,那么您需要在取消引用指针之前进行检查:
if (Customer * c = list.retrieve(i)) {
c->addAccount(acc);
} else {
// handle the error?
}
并且,出于礼貌,您应该返回看起来更像空指针的内容,例如nullptr
,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
函数中。
答案 1 :(得分:0)
- 为什么不首先操纵Customer对象?
醇>
是的,你是对的。通过defualt其重新调整的by value
不是通过引用,因此列表中的原始对象未进行修改。
- 在我更改函数和函数调用之后,为什么它会给我上面提到的错误?
醇>
我认为你需要分享addAccount
方法的代码。问题可能在其中。
考虑到原始代码return by value
,它正在进行核心工作(毫无例外)。