简体   繁体   中英

How to change class member value in vector

#include <iostream>
#include <string>

using namespace std;

class Owner{
    protected:
        string ownerName;
        int balance;
        int numPetsCheckin;
        string pet[100];

    public:
        Owner();
        Owner(const string& ownerName, int balance);
        string getOwnerName(){return ownerName;}
        int getBalance(){return balance;}
        int getNumPetsCheckin(){return numPetsCheckin;}
     
        void pushListPet(string a){
            pet[numPetsCheckin] = a;
            numPetsCheckin++;
            //cout << numPetsCheckin;
        }
        void showOwners(){
            cout << "Owners { name: " << ownerName << ", balance: " << balance << ", numPetsCheckin: " << numPetsCheckin << "}\n";
        }

};

Owner:: Owner()
    : ownerName("No name"), balance(0), numPetsCheckin(0){}
Owner:: Owner(const string& theName, int theBalance)
    : ownerName(theName), balance(theBalance), numPetsCheckin(0){}


int main(){
    int people = 0;
    Owner owner[100]; 

    Owner A( "A", 10); 
    owner[people] = A;
    people++;
    
    Owner B("B", 20);
    owner[people] = B;
    people++;
    A.showOwners();
    A.pushListPet("momo");
    A.showOwners();

    cout << "owner[0].getOwnerName: " << owner[0].getOwnerName() << endl;
    cout << "owner[0].getNumPetsCheckin: " << owner[0].getNumPetsCheckin() << endl;
    cout << "A.getNumPetsCheckin: " << A.getNumPetsCheckin() << endl;
}


Owners { name: A, balance: 10, numPetsCheckin: 0}
Owners { name: A, balance: 10, numPetsCheckin: 1}
owner[0].getOwnerName: A 
owner[0].getNumPetsCheckin: 0
A.getNumPetsCheckin: 1

Q: why owner[0].getNumPetsCheckin() and A.getNumPetsCheckin() are different?

I set A's numPetsCheckin plus 1 in A.pushListPet("momo"){(numPetsCheckin++;)} , but owner[0].getNumPetsCheckin() still 0...

A and owner[0] are different?

Q: How can solve it?????????????????

As people have explained in the comments, the bytes representing A and owner[0] were different. One can store pointers to point to the same memory, but often the intent is simply to store in some contiguous memory and access specific points in it.

Consider making A and B the references (which the compiler may implement as pointers in some cases) rather than making an array of pointers.

Owner& A = owner[people];
A = Owner("A",10);
people++;
...

Q: why owner[0].getNumPetsCheckin() and A.getNumPetsCheckin() are different?


They are different objects, after the satement owner[people] = A; , the object A is copied to owner[people] . You can verify it with print the address:

  std::cout << &owner[people] << ' ' << &A << std::endl;

Got output on my machine, they are different objects. So you change on object A doesn't affect owner[people]

0x7ffd10410f90 0x7ffd1040f530

Q: How can solve it?


Use a reference:

  auto& Aref = owner[0];
  Aref.showOwners();
  Aref.pushListPet("momo");
  Aref.showOwners();

Or directly modify the object owner[0]

  owner[0].showOwners();
  owner[0].pushListPet("momo");
  owner[0].showOwners();

Your code does not make good use of modern c++ as the comments mentioned, I just refine it with c++17 to make it more clear:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Owner {
 protected:
  // default value
  std::string ownerName = "No name";
  int balance = 0;
  // use vector instead of fixed sized array
  std::vector<std::string> pet;

 public:
  // the default construct is enough
  Owner() = default;
  Owner(const string &ownerName, int balance);
  string getOwnerName() { return ownerName; }
  int getBalance() { return balance; }
  // just return the size of vector
  int getNumPetsCheckin() { return pet.size(); }
  // move the temporary argument
  void pushListPet(string a) { pet.push_back(std::move(a)); }
  void showOwners() {
    cout << "Owners { name: " << ownerName << ", balance: " << balance
         << ", numPetsCheckin: " << getNumPetsCheckin() << "}\n";
  }
};

Owner::Owner(const string &theName, int theBalance)
    : ownerName(theName), balance(theBalance) {}

int main() {
  // use vector instead of fixed sized array
  std::vector<Owner> owner;
  // emplace back will construct a new object at the end of vector, and return
  // the reference
  auto &a = owner.emplace_back("A", 10);
  a.showOwners();
  a.pushListPet("momo");
  a.showOwners();

  // construct a new object at the end of vector, again
  owner.emplace_back("B", 20);

  cout << "owner[0].getOwnerName: " << owner[0].getOwnerName() << endl;
  cout << "owner[0].getNumPetsCheckin: " << owner[0].getNumPetsCheckin()
       << endl;
  // The reference object a is invalidated, since the vector have growed size,
  // now we can only reference it with only `owner[0]` or owner.front()
  cout << "A.getNumPetsCheckin: " << owner.front().getNumPetsCheckin() << endl;
}

Online demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM