1

Sorry for grammar, not a native speaker.

So I've got an assignment to create a simple program where you should be able to create three people, pass in their name, country, occupation and phone number. You should be able to print out saved information as a spreadsheet.

So I came up with this kind of piece of code:

#include <iostream>
#include <iomanip>

using namespace std;

class Person {
public:
    string surname;
    string name;
    string country;
    string occupation;
    string phone;

    // Set default value
    Person() {
        surname = "empty";
        name = "empty";
        country = "empty";
        occupation = "empty";
        phone = "empty";
    }

    // SET PERSON'S DATA
    void set_surname(string entered_surname) {
        surname = entered_surname;
    }

    void set_name(string entered_name) {
        name = entered_name;
    }

    void set_country(string entered_country) {
        country = entered_country;
    }

    void set_occupation(string entered_occupation) {
        occupation = entered_occupation;
    }

    void set_phone(string entered_phone) {
        phone = entered_phone;
    }

    // RETURN PERSONS DATA
    string get_surname() {
        return surname;
    }
    string get_name() {
        return name;
    }
    string get_country() {
        return country;
    }
    string get_occupation() {
        return occupation;
    }
    string get_phone() {
        return phone;
    }

};

void create_a_frankenstein(Person person) {
    string entered_data;
    cout << "Please, enter person's surname: \n";
    cin >> entered_data;
    person.set_surname(entered_data);

    cout << "Please, enter person's name: \n";
    cin >> entered_data;
    person.set_name(entered_data);

    cout << "Please, enter person's country: \n";
    cin >> entered_data;
    person.set_country(entered_data);

    cout << "Please, enter person's occupation: \n";
    cin >> entered_data;
    person.set_occupation(entered_data);

    cout << "Please, enter person's phone: \n";
    cin >> entered_data;
    person.set_phone(entered_data);
}

int main() {

    Person fst;
    Person snd;
    Person trd;
    Person group[3] = {fst, snd, trd};

    int people_created = 0;

    bool switch_on = true;

    while (switch_on) {
        cout << "What operation would you like to perform: \n";
        cout << "    1) Create new person \n";
        cout << "    2) Print out all of the available information \n";
        cout << "    3) Quit \n";


        //Get the number of operation to perform
        int operation;
        cout << "Please, enter a number: \n";
        cin >> operation;

        switch (operation) {
        //Option 1: create a person
        case 1:
            if (people_created == 3) {
                cout << "It is not possible to create more that three people";
            }

        else {
                create_a_frankenstein(group[people_created]);
                people_created++;
            }
            break;

        //Option 2: print out all of the available information
        case 2:
            for (int i = 0; i < 3; i++) cout << setw(20) << setfill(' ') << left << group[i].get_surname();
            for (int i = 0; i < 3; i++) cout << setw(20) << setfill(' ') << left << group[i].get_name();
            for (int i = 0; i < 3; i++) cout << setw(20) << setfill(' ') << left << group[i].get_country();
            for (int i = 0; i < 3; i++) cout << setw(20) << setfill(' ') << left << group[i].get_occupation();
            for (int i = 0; i < 3; i++) cout << setw(20) << setfill(' ') << left << group[i].get_phone();
            break;

        // Option 3: quit
        case 3:
            switch_on = false;
            break;
        }
    }

}

Everything seem to work just fine. Except it doesn't change information in object's variables.

My guess is that when I pass a Person-type object to create_a_frankenstein(), method creates a copy of an object and starts working with a copy without changing anything in the original object.

I've tried to use pointer. I manage to do what I intend to on simplier examples:

void first(int* a){
    for (int i = 0; i < 7; i++) {
        a[i] = a[i]+1;
    }
}

int main() {
    int a[7] = {0, 1, 2, 3, 4, 5, 6};
    for (int i=0; i<7; i++) {
        cout << a[i] << ' ';
    }
}

But when I try to use it in the Lab, it doesn't work as easily.

Will be glad to receive any advices on how to solve the problem and what topics I should brush up or look deeper in. Thank you in advance!

  • 3
    You might want to have a look at references. If I understand you correctly, they do exactly what you want. – Jerome Reinländer Jun 01 '18 at 10:43
  • 1
    `a[i] = a[i]++` is invalid and invokes *undefined behavior*. Don't do the assignment, it will be done anyway. – Some programmer dude Jun 01 '18 at 10:43
  • 1
    Your function takes a Person by value, meaning you get a copy of whatever the caller had. Then you change your copy, without touching anything outside the function. Using references as Jerome says is better style in C++, but pointers would also work. – Useless Jun 01 '18 at 10:45
  • 1
    Alternatively, have `create_a_frankenstein` actually *return* a `Person` and ditch the argument entirely. – WhozCraig Jun 01 '18 at 10:48
  • @JeromeReinländer, thanks! That was the exact thing I needed. – Vanity Aloe Jun 01 '18 at 11:14
  • @Someprogrammerdude, sorry, a typo :) Well, the assignment will not be done by itself :) – Vanity Aloe Jun 01 '18 at 11:15

2 Answers2

2

Try to pass your Person objects by reference. You can find more here: passing object by reference in C++. Btw in your code example you don't call your function named 'first'.

MariiaZ
  • 56
  • 10
1

The problem is on the void create_a_frankenstein(Person person) method.

You are passing a copy of the Person's object. If you want to keep the changes made to an object pass it as a reference: void create_a_frankenstein(Person& person)

Note:

  1. Don't use arrays. Use std::vector instead if you want to store sequences of objects.

  2. It would be nice if you define any getter member function as const --> return_type getter_name(params) const { //body here}

KostasRim
  • 2,053
  • 1
  • 16
  • 32
  • 1
    Thank you for your answer. That was the exact thing that I needed :) If you don't mind, could you extend your answer and tell me why would it be better to use vector for objects? – Vanity Aloe Jun 01 '18 at 11:19
  • @VanityAloe its because a) vectors manage the lifetime of an object for you, that is, the follow RAII (although your case is simpler is good to know. b) you are actually storing 6 objects. 3 of them are fst, snd, thrd and 3 in the group. That is, the statement, `Person group[3] = {fst, snd, trd};` creates a copy of the objects inside the array. – KostasRim Jun 01 '18 at 11:29