3

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

3 回答 3

0

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

看这里。

Account* r1 =  bank->openNewAccount(thomas, 64363.32);
Account* r2 =  bank->openNewAccount(thomas, 41251.54);
Account* r3 =  bank->openNewAccount(thomas, 3232.32);

您为同一个所有者创建了三个帐户,并且一个帐户的所有者是 的参考成员Account。当您更改一个帐户的所有者时,您更改了 reference 的值owner,这是Personthomas 的别名。因此,其他帐户的值也会更改。

正如阿门所说,

int i = 10;
int& r1 = i;
int& r2 = i;
r1 = 4;
cout << i << r1 << r2; // gives 444

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

于 2013-05-19T12:52:28.220 回答
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++ 无法通过反复试验或所谓的教程正确学习。

于 2013-05-19T12:16:19.753 回答
0

有一个引用成员变量真的很讨厌:避免Person& owner;将它作为一个值。

原因是构造 Account 对象的东西可能超出范围,您将留下一个悬空引用

你的 Person 类也有一个问题,如果它被复制给另一个人;

Person a("name", 20);
Person b = a;

两者的名称数据都指向同一内存区域。不好,因为一个名字的改变也会改变另一个名字。为了解决这个问题,你必须重写复制构造函数,或者做其他类似的事情......

此外,用于构造 Person 的名称数据也可能超出范围,您将遇到访问冲突!在我上面使用你的类的方式中,我会遇到问题,因为常量字符串“name”会在第一个';'之后超出范围。

你最好的选择是使用 std::string 名称,因为我看到你已经在使用 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";
    }
};
于 2013-05-19T12:16:22.307 回答