2013-05-19 1 views
3

Account 클래스의 멤버 인 Person 클래스를 만들고 vectorAccounts 인 클래스 Bank이 있습니다.하나의 개체에 대한 참조가 변경되어 컬렉션에서 모두 변경됨

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

규칙 3/5를 따라야합니다. –

답변

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 + +가 시행 착오 또는 소위 지도서에 의해 제대로 배울 수 없기 때문에 좋은 책에 투자 할 것을 강력히 권합니다.

+0

불행히도 선생님은 onwer를 '&'not'*'로 원합니다. 나는 이상한 요구 때문에 매주 문제가 있습니다. 그 위에 갈 방법이 있습니까? – user2398815

+0

@ user2398815 : int를 사용하여 예제를 보았습니까? 그래서, 아니오, 당신이 사람이 하나 이상의 계정을 소유 할 수 없다고 말하면, 나는 그 주위에 방법을 보지 못합니다. –

+0

@ user2398815 : 그런데 새로운 질문마다 새 계정을 만들지 마십시오. 그건 stackoverflow 커뮤니티에 대해 무례한 일입니다. –

0

참조 멤버 변수를 사용하는 것은 정말 불쾌합니다. 피하십시오 Person& owner; 그냥 값으로 사용하십시오.

계정 개체를 구성하는 것은 범위를 벗어날 수 있으며 매달아 참조으로 남게됩니다.

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"; 
    } 
}; 
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 

는 또한 참조 초기화되어야 여기서주의하고 재 할당 될 수있다 : 그 별명의 초기 값. 재 할당은 이니셜 라이저의 값을 변경하는 것을 의미합니다.

관련 문제