更改一个对象的引用,并在集合中为所有对象更改

时间:2013-05-19 12:13:24

标签: c++ collections reference

我创建了类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;
}

3 个答案:

答案 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)

  

引用是对象的别名或替代名称。所有   应用于对象的操作的操作   参考参考。引用的地址是地址   别名对象。

See here.

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

此处还要注意,必须初始化引用(函数参数除外!),并且不能重新分配:它是其初始化值的别名。因此,重新分配只会改变初始化程序的值。