我创建了类Person
,它是类Account
的成员,然后是Bank
类,其中包含vector
Accounts
。
我创建了一个Person
谁拥有3 Accounts
然后我想changeOnwner()
一个帐户,但不小心所有帐户都获得了这个新的所有者。代码正在运行,而且非常直观。 我不明白为什么所有3个帐户中的参考都发生了变化。如何解决这个问题?
#include <iostream>
#include <vector>
using namespace std;
class Person{
public:
char* name;
int age;
Person(char* name, int age){
this->name = name;
this->age = age;
}
~Person(){
}
void show(){
cout<<name<<" "<<age<<" yo";
}
};
class Account{
public:
Person& owner;
double money;
Account(Person* owner, double money):
owner(*owner) , // this->owner = *owner;
money(money) { //Uninitialized reference member
}
void show(){
cout<<"\n-------------\n";
owner.show();
cout<<endl;
cout<<money<<" USD\n-------------";
}
};
class Bank{
public:
vector<Account*>* v;
Bank(){
v = new vector<Account*>();
}
Account* openNewAccount(Person* client, double money){
Account* r = new Account(client, money);
v->push_back(r);
return r;
}
void zmienWlasciciela(Person& o, Account* r){
r->owner = o;
}
void usunRachunek(Account* r){
delete r;
}
void show(){
for(int i = 0; i < v->size(); i++)
v->at(i)->show();
}
~Bank(){
delete v;
}
};
int main(){
Bank* bank = new Bank();
Person* thomas = new Person("thomas", 34);
Account* r1 = bank->openNewAccount(thomas, 64363.32);
Account* r2 = bank->openNewAccount(thomas, 41251.54);
Account* r3 = bank->openNewAccount(thomas, 3232.32);
bank->show();
Person* margaret = new Person("Margaret", 23);
bank->zmienWlasciciela(*margaret, r2);
cout<<"I have changed owner of account r2"<<endl;
bank->show();
return 0;
}
答案 0 :(得分:0)
r->owner = o;
所有者是一个参考。你好像不明白引用是如何工作的。见这个例子:
int i = 10;
int& r1 = i;
int& r2 = i;
int& r3 = i;
int j = 4;
r1 = j;
cout << i << r1 << r2 << r3; //output is 4444
也许所有者应该是指针。
如果您来自C#或Java背景说明,C#和Java中的引用更像是C ++中的指针。参考的C ++概念可以说更像是C#ref
函数参数,但不限于函数参数。我再次强烈建议您投入一本好书,因为C ++无法通过反复试验或所谓的教程来学习。
答案 1 :(得分:0)
真的很讨厌拥有引用成员变量:避免Person& owner;
只需将其作为值。
原因是构造Account对象的东西可能超出范围,你将留下悬空引用。
你的Person类也有一个问题,如果它被复制到另一个人;
Person a("name", 20);
Person b = a;
两者的名称数据都指向同一内存区域。一个名称更改不好也会改变另一个名称。为了解决这个问题,你必须覆盖复制构造函数,或者做一些像这样的事情......
用于构建Person的名称数据也可能超出范围,您将获得访问冲突!在我上面使用你的课程的方式中,我会遇到问题,因为常量字符串“name”会在第一个';'之后超出范围。
你最好的选择是使用std :: string name,因为我看到你已经在使用stl。
全部放在一起,
class Person{
public:
std::string m_name;
unsigned m_age;
Person(char* name, unsigned age) :
m_name(name),
m_age(age)
{
}
~Person()
{
}
void show(){
cout<<m_name.c_str()<<" "<<age<<" yo";
}
};
答案 2 :(得分:0)
引用是对象的别名或替代名称。所有 应用于对象的操作的操作 参考参考。引用的地址是地址 别名对象。
Account* r1 = bank->openNewAccount(thomas, 64363.32);
Account* r2 = bank->openNewAccount(thomas, 41251.54);
Account* r3 = bank->openNewAccount(thomas, 3232.32);
您为同一所有者创建了三个帐户,并且帐户的所有者是Account
的参考成员。当您更改一个帐户的所有者时,您更改了引用owner
的值,这是Person
托马斯的别名。因此,其他账户的价值也会发生变化。
正如亚美尼亚所说,
int i = 10;
int& r1 = i;
int& r2 = i;
r1 = 4;
cout << i << r1 << r2; // gives 444
此处还要注意,必须初始化引用(函数参数除外!),并且不能重新分配:它是其初始化值的别名。因此,重新分配只会改变初始化程序的值。